问题
The following piece of code compiles just fine:
#include <boost/serialization/shared_ptr.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <sstream>
#include <memory>
struct A {
int i;
A(): i(0) {}
A(int i): i(i) {}
template <typename Archive>
void serialize(Archive& ar, const unsigned int) {
ar & i;
}
};
int main() {
auto a = std::make_shared<A>(465);
std::stringstream stream;
boost::archive::text_oarchive out{stream};
out << a;
}
Now I would expect that if I replace A
with int
then it should also work.
#include <boost/serialization/shared_ptr.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <sstream>
#include <memory>
int main() {
auto a = std::make_shared<int>(465);
std::stringstream stream;
boost::archive::text_oarchive out{stream};
out << a;
}
However, this code doesn't compile, but gives an assertion failure:
In file included from main.cpp:1:
/usr/local/include/boost/serialization/shared_ptr.hpp:277:5: error: static_assert failed "boost::serialization::tracking_level< T >::value != boost::serialization::track_never"
BOOST_STATIC_ASSERT(
^
...
Am I doing something wrong or is this a bug in Boost?
回答1:
From the Boost source code around that assertion:
// The most common cause of trapping here would be serializing
// something like shared_ptr<int>. This occurs because int
// is never tracked by default. Wrap int in a trackable type
BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
Basically, in order to serialize things like shared_ptr
properly, the pointed-to objects need to be centrally tracked during the serialization process (to identify when multiple pointers point to the same object, so they don't lead to two copies of the object being serialized). Tracking an object is more expensive than not tracking it, though, so primitive types are not tracked (the assumption being that there's gonna be a lot of them). Essentially, this makes it impossible to serialize shared_ptr<primitive_type>
without mucking with the Boost sources. The solution, as the comment says, is to instead serialize some UDT containing an int.
来源:https://stackoverflow.com/questions/32058093/boost-serialization-doesnt-work-with-shared-ptrint