boost::serialization - serializing boost::smart_ptrs won't work
Hello,
I have a problem with serializing smart_ptrs. I have tried both the
boost::scoped_ptr and the boost::shared_ptr but I get always the same error:
Boost1-33\include\boost-1_33\boost\archive\detail\oserializer.hpp(566):
error C2027: Use of undefined type "boost::STATIC_ASSERTION_FAILURE<x>"
with
[
x=false
]
My example program:
#include
Sascha Friedmann wrote:
Hello, I have a problem with serializing smart_ptrs. I have tried both the boost::scoped_ptr and the boost::shared_ptr but I get always the same error:
Boost1-33\include\boost-1_33\boost\archive\detail\oserializer.hpp(566): error C2027: Use of undefined type "boost::STATIC_ASSERTION_FAILURE<x>" with [ x=false ]
int main( int argc, char* argv[] )
{
**** replace the following
Test t;
with const Test t;
std::ofstream ofs( "test.txt" );
boost::archive::text_oarchive out( ofs );
out << t;
}
I hope someone can help me (google and the documentation couldn't :()
This is explained in couple of places: a) The code comment at the point where the compile time error occurs gives and explanation and points to more information. b) The Rationale section of the documentation explains this in detail and why this is trapped.
Sascha Friedmann
Robert Ramey wrote:
Sascha Friedmann wrote:
Hello, I have a problem with serializing smart_ptrs. I have tried both the boost::scoped_ptr and the boost::shared_ptr but I get always the same error:
Boost1-33\include\boost-1_33\boost\archive\detail\oserializer.hpp(566): error C2027: Use of undefined type "boost::STATIC_ASSERTION_FAILURE<x>" with [ x=false ]
int main( int argc, char* argv[] )
{
**** replace the following
Test t;
with
const Test t;
std::ofstream ofs( "test.txt" );
boost::archive::text_oarchive out( ofs );
out << t;
}
I hope someone can help me (google and the documentation couldn't :()
This is explained in couple of places:
a) The code comment at the point where the compile time error occurs gives and explanation and points to more information. b) The Rationale section of the documentation explains this in detail and why this is trapped.
Sascha Friedmann
I was reading the explanation an the rationale's explanation, but I didn't understand it then, but now I think I understand it. Thank you.
Sascha Friedmann
Sascha Friedmann wrote:
Hello, I have a problem with serializing smart_ptrs. I have tried both the boost::scoped_ptr and the boost::shared_ptr but I get always the same error:
Boost1-33\include\boost-1_33\boost\archive\detail\oserializer.hpp(566): error C2027: Use of undefined type "boost::STATIC_ASSERTION_FAILURE<x>" with [ x=false ]
int main( int argc, char* argv[] )
{
**** replace the following
Test t;
with
const Test t;
std::ofstream ofs( "test.txt" );
boost::archive::text_oarchive out( ofs );
out << t;
}
I hope someone can help me (google and the documentation couldn't :()
This is explained in couple of places:
a) The code comment at the point where the compile time error occurs gives and explanation and points to more information. b) The Rationale section of the documentation explains this in detail and why this is trapped.
Sascha Friedmann
I understand now the problem, but in my real project I ran again into
Robert Ramey wrote: this trap. After rereading the article in the rationale I understand fully why it is trapping, but I don't want to set my class to track_never because I can't guarantee that it is what I want. And const_cast is no solution, too. So the thing that is left is this construct_from class-wrapper. But it seems it is only an example an not a part of the boost::serialization library. How do I write my own construct_from wrapper, that can wrap all my objects, so that I can still create them non-const on the stack and use them and for serializing I'm just creating such a construct_from wrapper for an object? While writing I'm wondering now if I'm not bypassing the system with this.. Sascha Friedmann
Sascha Friedmann wrote:
I understand now the problem, but in my real project I ran again into this trap. After rereading the article in the rationale I understand fully why it is trapping, but I don't want to set my class to track_never because I can't guarantee that it is what I want.
Hmm - you want to make unmaintainable code? If this is what you want - just comment out the trap in your own copy of iserializer.hpp and you'll be done.
const_cast is no solution, too.
Why not? It's explictly designed to permit override of "const" where the user is more knowledgable than the library writer regarding what he want's to do. That's the situation here. It might also serve as a "red flag" for the programmer which has to fix your program in the future when it breaks.
So the thing that is left is this construct_from class-wrapper. But it seems it is only an example an not a part of the boost::serialization library.
I have no idea what construct_from class-wrapper refers to. Robert Ramey
Robert Ramey wrote:
Sascha Friedmann wrote:
I understand now the problem, but in my real project I ran again into this trap. After rereading the article in the rationale I understand fully why it is trapping, but I don't want to set my class to track_never because I can't guarantee that it is what I want.
Hmm - you want to make unmaintainable code? If this is what you want - just comment out the trap in your own copy of iserializer.hpp and you'll be done.
For now I set them to track_never. I'm not 100% sure but for now it serves for me and when I need to save through a pointer the trap will show me that I have to refactor my broken code.
const_cast is no solution, too.
Why not? It's explictly designed to permit override of "const" where the user is more knowledgable than the library writer regarding what he want's to do. That's the situation here. It might also serve as a "red flag" for the programmer which has to fix your program in the future when it breaks.
Well, when I'm using a const object I have to cast the constness away before I can make a call to any non-const member-function and when I have to cast the constness away before searializing how comes it that the library knows at all, that this object is in reality a const object?
I have now another problem, too. When I am loading a map that contains a shared_ptr I have memory leaks, because the use_count is wrong. In my real project I have a use_count of 5, but I can get it down to 2, when I am using new to create the object, that has the map. I've written a small example, that is basically the same as my real project, but it has also a use_count of 2 after loading the map in:
#include
#include #include
#include #include #include
#include <fstream>
struct ATest { int i; ATest() : i( 1 ) { } virtual ~ATest(){}
template< class Archive > void serialize( Archive& ar, const unsigned ) { ar & i; } }; BOOST_CLASS_EXPORT( ATest )
struct BTest : ATest { int c; BTest() : c( 2 ) { }
template< class Archive > void serialize( Archive& ar, const unsigned ) { ar & boost::serialization::base_object< ATest >( *this ); ar & c; }
}; BOOST_CLASS_EXPORT( BTest )
typedef std::map< int, boost::shared_ptr< ATest > > MyMap;
BOOST_CLASS_TRACKING( MyMap, boost::serialization::track_never)
int main() { MyMap myMap; myMap[ 0 ] = boost::shared_ptr< ATest >( new BTest ); myMap[ 1 ] = boost::shared_ptr< ATest >( new BTest );
std::ofstream ofs( "map.txt" ); boost::archive::text_oarchive oar( ofs );
oar << myMap;
ofs.close();
std::ifstream ifs( "map.txt" ); boost::archive::text_iarchive iar( ifs );
MyMap myMap1;
iar >> myMap1; }
Maybe you can tell me what I am doing wrong :-) Sascha Friedmann
I have to recall my leaking problem. After searching for 2hours I posted here and 10minutes later after rereading the examples I found the solution. The problem was that I haven't used the BOOST_SERIALIZATION_NVP() macro. And I'm sorry in my example is actually no leak (and in the pointer version, too), it seems it was only due to an internal copy. I am very sorry, but to get the hang onto the serialization framework is actually quite hard if you're new to the whole serialization thing. Now I can finally go to bed, sleep well. Sascha Friedmann
participants (2)
-
Robert Ramey
-
Sascha Friedmann