Как сериализовать производные классы шаблонов с помощью Boost.serialize?

Я хотел бы сериализовать /unserialize следующие классы:

class Feature{
...
virtual string str()=0;
};

template<typename T>
class GenericFeature : public Feature{
T value;
...
virtual string str();
};

Я прочитал boost.serialize docs и сказал, что вы должны регистрировать классы.  Я могу зарегистрировать их в конструкторе. Но будут проблемы с загрузкой, так как регистрация будет динамической, а не статической (Как я понял, вы должны регистрировать классы до сериализации/десериализации).

Как сохранить/загрузить эти типы классов?

Ответ 1

Сначала сообщите, что функция абстрактна, не всегда нужна:

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Feature);

Метод сериализации должен выглядеть примерно так:

template<class Archive> 
void Feature::serialize(Archive & ar, const unsigned int version)
{
   ar & BOOST_SERIALIZATION_NVP(some_member);
}


template<typename T,class Archive> 
void GenericFeature<T>::serialize(Archive & ar, const unsigned int version)
{
   ar & boost::serialization::base_object<Feature>(*this);  //serialize base class
   ar & BOOST_SERIALIZATION_NVP(some_other_member);
}

Теперь сложной задачей является регистрация класса в serialize/deserialize:

boost::archive::text_iarchive inputArchive(somesstream);

boost::archive::text_oarchive outputArchive(somesstream);

//something to serialize
Feature* one = new GenericFeature<SomeType1>();
Feature* two = new GenericFeature<SomeType2>();
Feature* three = new GenericFeature<SomeType3>();

//register our class, must be all of posible template specyfication    
outputArchive.template register_type< GenericFeature<SomeType1> >();
outputArchive.template register_type< GenericFeature<SomeType2> >();
outputArchive.template register_type< GenericFeature<SomeType3> >();

// now simply serialize ;-]
outputArchive << one << two << three;

// register class in deserialization
// must be the same template specification as in serialize
// and in the same correct order or i'm get it wrong ;-D   
inputArchive.template register_type< GenericFeature<SomeType1> >();
inputArchive.template register_type< GenericFeature<SomeType2> >();
inputArchive.template register_type< GenericFeature<SomeType3> >();

Feature* another_one;
Feature* another_two;
Feature* another_three;

// and deserialize ;-]
inputArchive >> another_one >> another_two >> another_three;

Если вам нужно скрыть явное регистрацию где-нибудь и сделать его более автоматическим, есть идея создать специальный шаблон-функтор, который зарегистрирует один производный класс, создаст все доступный и поместит в один список, чтобы один статический метод класса Feature регистрировался торговый центр. Однако проблема будет в том, что вам нужна регистрация для всей версии архива, прямо сейчас я не знаю, будет ли полиморфный архив выполнять эту работу или нет.