В моем приложении у меня есть ряд классов, которые я хочу иметь возможность сериализации. Таким образом, каждый класс, экземпляры которого должны быть сериализуемыми, имеет следующее:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
// ar & (all data members)
}
Чтобы сериализовать объект, мне нужно использовать этот код вне класса:
ObjectToSerialize obj;
stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << obj;
Этот второй блок кода раздражает меня, потому что я должен использовать его каждый раз, когда хочу сериализовать объект. Можно ли как-нибудь переместить этот код в одно место и вызвать его, когда мне нужно сериализовать объект?
Я мог бы иметь объект с этим методом:
string serializeObject(Serializable obj)
Но проблема в том, что нет способа определить, какие объекты являются «сериализуемыми», поскольку нет супертипа, который класс должен реализовать при добавлении функциональности бустеризации.
Итак, как я могу разместить этот код в одном месте и разрешить передачу только сериализуемых объектов в метод?
Создайте шаблонную функцию, которая принимает объект с функцией сериализации.
template <typename T> std::string serializeObject(T obj) {
stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << obj;
//...
}std:String str = serializeObject(ObjectToSerialize);
Все просто: вам не нужен и нужен базовый класс для этих объектов. Так что вместо динамического полиморфизма используйте статический полиморфизм:
template <class Serializable>
std::string serializeObject(Serializable& s)
{
stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << obj;
return ss.str();
}
Теперь, если вы передадите что-то в функцию, которая не сериализуется, вы получите ошибку компилятора. Чтобы сделать ошибку более читабельной, вы можете попробовать использовать некоторые методы, основанные на SFINAE, такие как std::enable_if