У меня есть проект C++/CLI, который использует сериализацию boost для сериализации трех разных классов. Я хотел бы знать, можно ли проанализировать первую строку архива последовательной передачи, чтобы узнать, какой класс был сериализован в этом архиве, а затем создать объект соответствующего класса и десериализовать архив в объекте. Эта строка будет содержать идентификатор (возможно, int или значение класса enum), чтобы определить, какой класс был сериализован.Ускорение сериализации: читать данные различного типа
3
A
ответ
2
Формат файла уже обрабатывается по вашему выбору реализации архива.
На практике это было бы boost::archive::text_oarchive
, boost::archive::binary_oarchive
, boost::archive::xml_oarchive
.
До тех пор, пока ваш тип архива не изменится, вы можете очень легко использовать вариант Boost для отличия ваших полезных нагрузок. Другими словами, сделайте сериализационную структуру для вас работой, а не «прокладывайте ее» вокруг нее:
Вот демоверсия, которая сериализует 3 разные (составные) полезные и круговые повороты просто отлично, без внешних знаний о полезной нагрузке на самом деле там :
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/variant.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/access.hpp>
struct A {
int simple;
private:
friend class boost::serialization::access;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar & simple;
}
};
struct B {
std::string text;
private:
friend class boost::serialization::access;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar & text;
}
};
struct C {
A composed_a;
B composed_b;
private:
friend class boost::serialization::access;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar & composed_a & composed_b;
}
};
struct FileContents { // conventions...
boost::variant<A, B, C> payload;
private:
friend class boost::serialization::access;
template <typename Ar> void serialize(Ar& ar, unsigned) {
ar & payload;
}
};
#include <sstream>
#include <boost/lexical_cast.hpp>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// For our roundtrip test, implement streaming as well so we can independently check equivalence
inline static std::ostream& operator<<(std::ostream& os, A const& v) {
return os << "A{" << v.simple << "}";
}
inline static std::ostream& operator<<(std::ostream& os, B const& v) {
return os << "B{" << v.text << "}";
}
inline static std::ostream& operator<<(std::ostream& os, C const& v) {
return os << "C{" << v.composed_a << ", " << v.composed_b << "}";
}
void roundtrip_test(FileContents const& original) {
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
oa << original;
}
{
boost::archive::text_iarchive ia(ss);
FileContents clone;
ia >> clone;
std::string const before = boost::lexical_cast<std::string>(original.payload);
std::string const after = boost::lexical_cast<std::string>(clone.payload);
std::cout << "Roundtrip '" << before << "': " << std::boolalpha << (before == after) << "\n";
}
}
int main() {
roundtrip_test({ A { 42 } });
roundtrip_test({ B { "Life The Universe And Everything" } });
roundtrip_test({ C { {42}, { "Life The Universe And Everything" } } });
}
выход существо:
Roundtrip 'A{42}': true
Roundtrip 'B{Life The Universe And Everything}': true
Roundtrip 'C{A{42}, B{Life The Universe And Everything}}': true
Это потрясающе. Структура FileContents - это то, что я пропустил. Большое спасибо. – DreamTool
Я попытался реализовать это решение сегодня утром, но я не понимаю, как правильно использовать boost :: variant. Я создал класс base_project, который имеет boost :: variant для элемента данных, но когда я передаю local_uni_project моей функции сериализации (которая принимает объект base_project во вводе), существует неприемлемое преобразование ошибка. –
DreamTool
Я могу только догадываться о вашем фактическом коде. Если эти типы имеют родственные типы (отношение наследования), могут быть неоднозначные преобразования. _ (Кроме того, в этом случае вы явно хотите зарегистрировать полиморфные типы для сериализации через указатель на базовый класс.) _. Если нет, можете ли вы показать [SSCCE] (http://sscce.org/)? – sehe