我有一个C ++ / CLI项目,它使用boost序列化来序列化三个不同的类。我想知道是否可以解析boost序列化归档的第一行,以便知道在此归档中序列化了哪个类,然后创建相应类的对象并将归档反序列化为对象。该行将包含一个ID(可能是枚举类的int或值),以标识序列化的类。
答案 0 :(得分:4)
您选择的存档实施已经处理了文件格式。
在实践中,boost::archive::text_oarchive
,boost::archive::binary_oarchive
,boost::archive::xml_oarchive
。
只要您的存档类型本身不变,您就可以非常轻松地使用Boost Variant来区分您的有效负载。换句话说,让序列化框架为您完成工作,而不是围绕它进行“管道编带”:
这是一个演示,可以序列化3个不同的(复合)有效载荷和往返,但实际上没有有效载荷的外部知识:
<强> Live On Coliru 强>
#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