Domanda

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);

È stato utile?

Soluzione

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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top