Boost C++ Libraries: Ticket #7474: compilation error in boost::serialization https://svn.boost.org/trac10/ticket/7474 <p> Error: passing 'const ... discards qualifiers' </p> <p> Related File: /opt/local/include/boost/serialization/split_member.hpp </p> <p> Root cause: In /opt/local/include/boost/serialization/split_member.hpp: calling access::member_save() with a "const &amp; T" </p> <pre class="wiki"> template&lt;class Archive, class T&gt; struct member_saver { static void invoke( Archive &amp; ar, const T &amp; t, const unsigned int file_version ){ access::member_save(ar, t, file_version); ^^ t is "const T&amp;" } }; </pre><p> But in the called, parameter t is not expecting "const". See file /opt/local/include/boost/serialization/access.hpp: </p> <pre class="wiki"> // pass calls to users's class implementation template&lt;class Archive, class T&gt; static void member_save( Archive &amp; ar, //const T &amp; t, T &amp; t, const unsigned int file_version ){ t.save(ar, file_version); } </pre><p> Error trace: </p> <ul><li>Invoking: GCC C++ Compiler </li><li>g++ -DOS_MACOSX -I/opt/local/gtest/include -I../third_party/leveldb-1.5.0/include -I../third_party/leveldb-1.5.0 -I/opt/local/include -I../src/server/cse -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"test/server/cse/bucket_addcells.d" -MT"test/server/cse/bucket_addcells.d" -o "test/server/cse/bucket_addcells.o" "../test/server/cse/bucket_addcells.cpp" </li><li>/opt/local/include/boost/serialization/access.hpp: In static member function 'static void boost::serialization::access::member_save(Archive&amp;, T&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, T = const cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]': </li><li>/opt/local/include/boost/serialization/split_member.hpp:43: instantiated from 'static void boost::serialization::detail::member_saver&lt;Archive, T&gt;::invoke(Archive&amp;, const T&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]' </li><li>/opt/local/include/boost/serialization/split_member.hpp:70: instantiated from 'void boost::serialization::split_member(Archive&amp;, T&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]' </li><li>../src/server/cse/io/sorted.hpp:56: instantiated from 'void cse::<a class="missing wiki">SortedBucket</a>&lt;KEY, VAL&gt;::serialize(Archive&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, KEY = int, VAL = float]' </li><li>/opt/local/include/boost/serialization/access.hpp:118: instantiated from 'static void boost::serialization::access::serialize(Archive&amp;, T&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]' </li><li>/opt/local/include/boost/serialization/serialization.hpp:69: instantiated from 'void boost::serialization::serialize(Archive&amp;, T&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]' </li><li>/opt/local/include/boost/serialization/serialization.hpp:128: instantiated from 'void boost::serialization::serialize_adl(Archive&amp;, T&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, T = cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]' </li><li>/opt/local/include/boost/archive/detail/oserializer.hpp:148: instantiated from 'void boost::archive::detail::oserializer&lt;Archive, T&gt;::save_object_data(boost::archive::detail::basic_oarchive&amp;, const void*) const [with Archive = boost::archive::text_oarchive, T = cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;]' ../test/server/cse/bucket_addcells.cpp:63: instantiated from here </li><li>/opt/local/include/boost/serialization/access.hpp:93: error: passing 'const cse::<a class="missing wiki">SortedBucket</a>&lt;int, float&gt;' as 'this' argument of 'void cse::<a class="missing wiki">SortedBucket</a>&lt;KEY, VAL&gt;::save(Archive&amp;, unsigned int) [with Archive = boost::archive::text_oarchive, KEY = int, VAL = float]' discards qualifiers </li></ul> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7474 Trac 1.4.3 Robert Ramey Sun, 21 Oct 2012 16:53:46 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7474#comment:1 https://svn.boost.org/trac10/ticket/7474#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> I'm guessing that the client code does something like </p> <p> myclass x; </p> <p> text_oarchive oa(... </p> <p> oa &lt;&lt; x; <em> error - x must be const !!! </em></p> <p> There is a long explanation in the rationale section of the manual which explains why this is so. </p> <p> Of course, without the rest of the program I can't verify whether my presumption is right or wrong about this. But for now, I'm going to assume I'm corrected and close this ticket. </p> <p> Robert Ramey </p> Ticket Like Gao <gao.like@…> Mon, 22 Oct 2012 20:30:27 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/7474#comment:2 https://svn.boost.org/trac10/ticket/7474#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> <p> Hi, I report this bug as it can be produced in below code --- where it doesn't matter if we use "const" Class in the client code or not. Thanks, -Like </p> <pre class="wiki"> //============================================================================ // Name : boost_bug.cpp // Author : // Version : // Copyright : Your copyright notice //============================================================================ #include &lt;iostream&gt; #include &lt;tr1/memory&gt; #include &lt;fstream&gt; #include &lt;iostream&gt; #include &lt;iostream&gt; #include &lt;boost/archive/text_oarchive.hpp&gt; class MyClassA { public: MyClassA(int x):xx(x){}; int xx; private: friend class boost::serialization::access; template&lt;class Archive&gt; void save(Archive &amp; ar, const unsigned int version) { //ar &lt;&lt; xx; } template&lt;class Archive&gt; void load(Archive &amp; ar, const unsigned int version) { //ar &gt;&gt; xx; } BOOST_SERIALIZATION_SPLIT_MEMBER(); }; int main() { MyClassA clsA(12); std::ofstream f("/tmp/boost_clsA", std::ios::binary); if (f.fail()) return -1; boost::archive::text_oarchive oa(f); oa &lt;&lt; clsA; f.close(); return 0; } </pre> Ticket Robert Ramey Mon, 22 Oct 2012 21:00:09 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7474#comment:3 https://svn.boost.org/trac10/ticket/7474#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <pre class="wiki">int main() { const MyClassA clsA(12); // error - should be "const" std::ofstream f("/tmp/boost_clsA", std::ios::binary); if (f.fail()) return -1; boost::archive::text_oarchive oa(f); oa &lt;&lt; clsA; f.close(); return 0; } </pre><p> Exactly as I expected. For this to compile you have to have the "const". </p> <p> The reason for this is explained in the Rationale section in the documentation. Please read it. </p> <p> Robert Ramey </p> Ticket Like Gao <gao.like@…> Tue, 23 Oct 2012 20:08:49 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/7474#comment:4 https://svn.boost.org/trac10/ticket/7474#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> <p> I have to report this again. Changing to const form also gave the exact same error: </p> <pre class="wiki">const MyClassA clsA(12); // error - should be "const" </pre><p> Please try this example with const form. I don't know if this work with VC but gcc always gave error even the const form. </p> <p> As in my first post, the issue appears due to the one line change in /opt/local/include/boost/serialization/access.hpp: </p> <pre class="wiki"> // pass calls to users's class implementation template&lt;class Archive, class T&gt; static void member_save( Archive &amp; ar, //const T &amp; t, // change to below T &amp; t, const unsigned int file_version ){ t.save(ar, file_version); } </pre> Ticket Robert Ramey Wed, 19 Feb 2014 19:33:40 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7474#comment:5 https://svn.boost.org/trac10/ticket/7474#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> The following compiles for me w/o problem. </p> <p> Note that I made one change - I added "const" to the save member function. </p> <pre class="wiki">//============================================================================ // Name : boost_bug.cpp // Author : // Version : // Copyright : Your copyright notice //============================================================================ #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;iostream&gt; #include &lt;iostream&gt; #include &lt;boost/archive/text_oarchive.hpp&gt; class MyClassA { public: MyClassA(int x):xx(x){}; int xx; private: friend class boost::serialization::access; template&lt;class Archive&gt; void save(Archive &amp; ar, const unsigned int version) const { //ar &lt;&lt; xx; } template&lt;class Archive&gt; void load(Archive &amp; ar, const unsigned int version) { //ar &gt;&gt; xx; } BOOST_SERIALIZATION_SPLIT_MEMBER(); }; int main() { MyClassA clsA(12); std::ofstream f("/tmp/boost_clsA", std::ios::binary); if (f.fail()) return -1; boost::archive::text_oarchive oa(f); oa &lt;&lt; clsA; f.close(); return 0; } </pre> Ticket