I had a similar problem. This seems like a mistake to me in VS2012 (and above). I was able to play this in a simple .cpp file, so I opened the connect ticket .
I believe this error is erroneously reported when all of the following conditions apply:
- The object is deserialized using Boost Serialization somewhere in the * .cpp file.
- The serialized object is "deep enough" (~ 5 levels - that is, A contains the vector B, B contains the vector C, etc. to E).
- Somewhere in the same * .cpp file (not necessarily in the same function) some template function is called.
An error is no longer reported if the object is resized to be smaller, or if the call to the template function is deleted.
In addition, this error is not reproduced in VS2010. I tested Boost versions 1.49, 1.52, 1.55.
Possible workaround: in one case, the error only appeared when using boost::serialization::object_serializable (and not by default object_class_info ). Therefore, switching to object_class_info can be a workaround, except that it will break compatibility with previously serialized data.
Possible workaround # 2: hide the template function call in a separate translation unit.
The following code reproduces the error:
#pragma warning(disable:4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data (problem in Boost, unrelated to the bug in question) #include <fstream> #include <boost/archive/binary_iarchive.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/map.hpp> #include <boost/serialization/version.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/access.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/shared_ptr_132.hpp> #include <boost/serialization/split_member.hpp> #include <boost/serialization/utility.hpp> struct E { int x; }; struct D { std::vector<E> children; }; struct C { std::vector<D> children; }; struct B { std::vector<C> children; }; struct A { std::vector<B> children; }; template<class Archive> void serialize(Archive & ar, A& obj, const unsigned int /*file_version*/) { ar & BOOST_SERIALIZATION_NVP(obj.children); } template<class Archive> void serialize(Archive & ar, B& obj, const unsigned int /*file_version*/) { ar & BOOST_SERIALIZATION_NVP(obj.children); } template<class Archive> void serialize(Archive & ar, C& obj, const unsigned int /*file_version*/) { ar & BOOST_SERIALIZATION_NVP(obj.children); } template<class Archive> void serialize(Archive & ar, D& obj, const unsigned int /*file_version*/) { ar & BOOST_SERIALIZATION_NVP(obj.children); } template<class Archive> void serialize(Archive & ar, E& obj, const unsigned int /*file_version*/) { ar & BOOST_SERIALIZATION_NVP(obj.x); } template<class T> boost::shared_ptr<T> UnrelatedTemplateFunc(const std::string & argument); #ifndef SER_CLASS #define SER_CLASS A #endif // serialize A and the build will fail (if UnrelatedTemplateFunc is called below) // serialize B instead of A and the build will succeed! void Func(boost::shared_ptr<SER_CLASS> obj) { std::ifstream ifs; boost::archive::binary_iarchive ia(ifs); ia >> obj; } void OtherFunc() { // comment this line and the build will succeed, whatever struct you decide to serialize above #ifndef DONT_CALL_FUNC UnrelatedTemplateFunc<unsigned char>(""); #endif }
Yodan tauber
source share