9
votes

I have a template class that I serialize (call it C), for which I want to specify a version for boost serialization. As BOOST_CLASS_VERSION does not work for template classes. I tried this:

namespace boost {
namespace serialization {
    template< typename T, typename U >
    struct version< C<T,U> >
    {
        typedef mpl::int_<1> type;
        typedef mpl::integral_c_tag tag;
        BOOST_STATIC_CONSTANT(unsigned int, value = version::type::value);
    };
}
}

but it does not compile. Under VC8, a subsequent call to BOOST_CLASS_VERSION gives this error:

error C2913: explicit specialization; 'boost::serialization::version' is not a specialization of a class template

What is the correct way to do it?

3
"but it does not compile". Can you give us some some information than that?? - Leon Timmermans
Under VC8: error C2913: explicit specialization; 'boost::serialization::version' is not a specialization of a class template on a subsequent call to BOOST_CLASS_VERSION. - Jazz
It looks correct. The error message seems to suggest you haven't included version.hpp - James Hopkin
That was the error! Thanks! What a pity I cannot vote for your comment because it is not formulated in an answer. - Jazz

3 Answers

13
votes
#include <boost/serialization/version.hpp>

:-)

1
votes

I was able to properly use the macro BOOST_CLASS_VERSION until I encapsulated it inside a namespace. Compilation errors returned were:

error C2988: unrecognizable template declaration/definition
error C2143: syntax error: missing ';' before '<'
error C2913: explicit specialization; 'Romer::RDS::Settings::boost::serialization::version' is not a specialization of a class template
error C2059: syntax error: '<'
error C2143: syntax error: missing ';' before '{'
error C2447: '{': missing function header (old-style formal list?)

As suggested in a previous edit, moving BOOST_CLASS_VERSION to global scope solved the issue. I would prefer keeping the macro close to the referenced structure.

0
votes

To avoid premature dependency of your library on Boost.Serialization you can forward declare:

namespace boost {
namespace serialization {

template<typename T> struct version;

}  // end namespace serialization
}  // end namespace boost

Instead of including the header. To declare the version of you class you can do:

namespace boost {
namespace serialization {
template<typename T, int D, class A>
struct version< your_type<T, D, A> > {
    enum { value = 16 };
};
}  // end namespace serialization
}  // end namespace boost

Since it doesn't use the BOOST_CLASS_VERSION macro still doesn't need premature inclusion of the Boost.Serialization headers.

(for some reason static const [constexpr] unsigned int value = 16; doesn't work for me, in C++14).