Question

I have a struct from external library for which I wrote some non-intrusive serialization methods. Also there's my wrapper for this struct, and I'm trying to keep all dependencies from external struct to this wrapper. The problem is, all serialization methods are template, so they are defined in header files and propagate dependency from the external library to everyone serializing the wrapper, which I'm trying to avoid. Is it possible to solve this problem?

UPD: Initially I had something like this:

// serialization.h

#include <external_library.h>

template <typename Archive>

void serialize(Archive& archive, ExternalStruct& external_struct, const unsigned int version) {
    // ...
}

Then I tried to make the serialization function non-template for the specific type of archive:

// serialization.h

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

struct ExternalStruct;

void serialize(boost::archive::binary_iarchive& archive, ExternalStruct& external_struct, const unsigned int version);
void serialize(boost::archive::binary_oarchive& archive, ExternalStruct& external_struct, const unsigned int version);

// serialization.cpp

#include <external_library.h>
#include "serialization.h"

void serialize(boost::archive::binary_iarchive& archive, ExternalStruct& external_struct, const unsigned int version) {
    // ...
}

void serialize(boost::archive::binary_oarchive& archive, ExternalStruct& external_struct, const unsigned int version) {
    // ...
}

But then I get many compile errors: no type named 'type' in 'struct boost::mpl::greater<boost::serialization::tracking_level<ExternalStruct>, mpl_::int_<0> >' BOOST_STATIC_WARNING(typex::value);

Was it helpful?

Solution

I think you will get nicer code if you keep template declaration in you header file

// serialization.h

#include <external_library.h>

struct ExternalStruct;
template <typename Archive>
void serialize(Archive& archive, ExternalStruct& external_struct, const unsigned int version);

You then put template implementation into your source file which hiding the details:

// serialization.cpp
#include "serialization.h"

#include <external_library.h>

template <typename Archive>
void serialize(Archive& archive, ExternalStruct& external_struct, const unsigned int version) 
{
    // ... details here
}

Finally you put "explicit instantiation" for specific archive types you plan to use. This code goes into the same source file as above.

// serialization.cpp continued 
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

template void serialize(boost::archive::binary_iarchive& archive,
     ExternalStruct& external_struct, const unsigned int version); // explicit instantiation.
template void serialize(boost::archive::binary_oarchive& archive,
     ExternalStruct& external_struct, const unsigned int version); // explicit instantiation.

OTHER TIPS

Of course this is possible. You could write a own function for each method you would like to use.

It's pretty ugly, to maintain, but a way you can use without any need of templates.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top