促进模板派生的序列化 class
Boost serialization of template derived class
我有一个模板化的基础 class Base
和一个模板化的派生 class Derived
我想序列化。
下面的简化代码编译 运行 但不序列化来自基 class 的数据成员。
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
template<class U, class V>
struct Base {
Base(U uu, V vv) : u(uu), v(vv) {}
U u;
V v;
};
template<class V, class T>
struct Derived : public Base<V, int>, public Base<V, std::string> {
Derived(T tt) : Base<V, int>(2.0, 4), Base<V, std::string>(3.0, std::string("hello")), t(tt) {}
T t;
};
// does not work
//BOOST_CLASS_EXPORT(Derived);
namespace boost { namespace serialization {
template<class Archive, class U, class V>
void serialize(Archive & ar, Base<U,V> &obj, const unsigned int version) {
ar& BOOST_SERIALIZATION_NVP(obj.u);
ar& BOOST_SERIALIZATION_NVP(obj.v);
}
template<class Archive, class V, class T>
void serialize(Archive & ar, Derived<V,T> &obj, const unsigned int version) {
boost::serialization::make_nvp("Base1",
boost::serialization::base_object<Base<V, int>>(obj) );
boost::serialization::make_nvp("Base2",
boost::serialization::base_object<Base<V, std::string>>(obj) );
// does not work
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, int>);
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, std::string>);
ar& BOOST_SERIALIZATION_NVP(obj.t);
}
}} // end namespace
int main() {
Derived<double, int> a(10);
std::ostringstream archive_ostream;
boost::archive::xml_oarchive oa(archive_ostream);
oa << BOOST_SERIALIZATION_NVP(a);
std::cout << archive_ostream.str() << std::endl;
}
输出仅为:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="12">
<a class_id="0" tracking_level="0" version="0">
<obj.t>10</obj.t>
</a>
那么如何获得 Base::u
和 Base::v
的序列化呢?我尝试使用 BOOST_CLASS_EXPORT(Derived);
但没有成功。
奖金问题:在这种情况下我如何也使用宏 BOOST_SERIALIZATION_BASE_OBJECT_NVP
?
您忘记实际将 NVP 写入存档:
ar & boost::serialization::make_nvp("Base1", boost::serialization::base_object<Base<V, int>>(obj) );
ar & boost::serialization::make_nvp("Base2", boost::serialization::base_object<Base<V, std::string>>(obj) );
更改后,它现在打印
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="12">
<a class_id="0" tracking_level="0" version="0">
<Base1 class_id="1" tracking_level="0" version="0">
<obj.u>2.00000000000000000e+00</obj.u>
<obj.v>4</obj.v>
</Base1>
<Base2 class_id="2" tracking_level="0" version="0">
<obj.u>3.00000000000000000e+00</obj.u>
<obj.v>hello</obj.v>
</Base2>
<obj.t>10</obj.t>
</a>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
template<class U, class V>
struct Base {
Base(U uu, V vv) : u(uu), v(vv) {}
U u;
V v;
};
template<class V, class T>
struct Derived : public Base<V, int>, public Base<V, std::string> {
Derived(T tt) : Base<V, int>(2.0, 4), Base<V, std::string>(3.0, std::string("hello")), t(tt) {}
T t;
};
// does not work
//BOOST_CLASS_EXPORT(Derived);
namespace boost { namespace serialization {
template<class Archive, class U, class V>
void serialize(Archive & ar, Base<U,V> &obj, const unsigned int /*version*/) {
ar& BOOST_SERIALIZATION_NVP(obj.u);
ar& BOOST_SERIALIZATION_NVP(obj.v);
}
template<class Archive, class V, class T>
void serialize(Archive & ar, Derived<V,T> &obj, const unsigned int /*version*/) {
ar & boost::serialization::make_nvp("Base1", boost::serialization::base_object<Base<V, int>>(obj) );
ar & boost::serialization::make_nvp("Base2", boost::serialization::base_object<Base<V, std::string>>(obj) );
// does not work
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, int>);
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, std::string>);
ar& BOOST_SERIALIZATION_NVP(obj.t);
}
}} // end namespace
int main() {
Derived<double, int> a(10);
std::ostringstream archive_ostream;
boost::archive::xml_oarchive oa(archive_ostream);
oa << BOOST_SERIALIZATION_NVP(a);
std::cout << archive_ostream.str() << std::endl;
}
我只回答 "bonus" 问题,因为 @sehe 已经回答了主要问题:
为了使用BOOST_SERIALIZATION_BASE_OBJECT_NVP
,serialize
必须是一个成员函数(见nvp.hpp
中的定义)。
以下工作:我必须对 Base 类 进行类型定义才能使宏工作:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
typedef Base<V, int> Base1;
typedef Base<V, std::string> Base2;
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
ar& BOOST_SERIALIZATION_NVP(t);
}
我有一个模板化的基础 class Base
和一个模板化的派生 class Derived
我想序列化。
下面的简化代码编译 运行 但不序列化来自基 class 的数据成员。
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
template<class U, class V>
struct Base {
Base(U uu, V vv) : u(uu), v(vv) {}
U u;
V v;
};
template<class V, class T>
struct Derived : public Base<V, int>, public Base<V, std::string> {
Derived(T tt) : Base<V, int>(2.0, 4), Base<V, std::string>(3.0, std::string("hello")), t(tt) {}
T t;
};
// does not work
//BOOST_CLASS_EXPORT(Derived);
namespace boost { namespace serialization {
template<class Archive, class U, class V>
void serialize(Archive & ar, Base<U,V> &obj, const unsigned int version) {
ar& BOOST_SERIALIZATION_NVP(obj.u);
ar& BOOST_SERIALIZATION_NVP(obj.v);
}
template<class Archive, class V, class T>
void serialize(Archive & ar, Derived<V,T> &obj, const unsigned int version) {
boost::serialization::make_nvp("Base1",
boost::serialization::base_object<Base<V, int>>(obj) );
boost::serialization::make_nvp("Base2",
boost::serialization::base_object<Base<V, std::string>>(obj) );
// does not work
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, int>);
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, std::string>);
ar& BOOST_SERIALIZATION_NVP(obj.t);
}
}} // end namespace
int main() {
Derived<double, int> a(10);
std::ostringstream archive_ostream;
boost::archive::xml_oarchive oa(archive_ostream);
oa << BOOST_SERIALIZATION_NVP(a);
std::cout << archive_ostream.str() << std::endl;
}
输出仅为:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="12">
<a class_id="0" tracking_level="0" version="0">
<obj.t>10</obj.t>
</a>
那么如何获得 Base::u
和 Base::v
的序列化呢?我尝试使用 BOOST_CLASS_EXPORT(Derived);
但没有成功。
奖金问题:在这种情况下我如何也使用宏 BOOST_SERIALIZATION_BASE_OBJECT_NVP
?
您忘记实际将 NVP 写入存档:
ar & boost::serialization::make_nvp("Base1", boost::serialization::base_object<Base<V, int>>(obj) );
ar & boost::serialization::make_nvp("Base2", boost::serialization::base_object<Base<V, std::string>>(obj) );
更改后,它现在打印
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="12">
<a class_id="0" tracking_level="0" version="0">
<Base1 class_id="1" tracking_level="0" version="0">
<obj.u>2.00000000000000000e+00</obj.u>
<obj.v>4</obj.v>
</Base1>
<Base2 class_id="2" tracking_level="0" version="0">
<obj.u>3.00000000000000000e+00</obj.u>
<obj.v>hello</obj.v>
</Base2>
<obj.t>10</obj.t>
</a>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
template<class U, class V>
struct Base {
Base(U uu, V vv) : u(uu), v(vv) {}
U u;
V v;
};
template<class V, class T>
struct Derived : public Base<V, int>, public Base<V, std::string> {
Derived(T tt) : Base<V, int>(2.0, 4), Base<V, std::string>(3.0, std::string("hello")), t(tt) {}
T t;
};
// does not work
//BOOST_CLASS_EXPORT(Derived);
namespace boost { namespace serialization {
template<class Archive, class U, class V>
void serialize(Archive & ar, Base<U,V> &obj, const unsigned int /*version*/) {
ar& BOOST_SERIALIZATION_NVP(obj.u);
ar& BOOST_SERIALIZATION_NVP(obj.v);
}
template<class Archive, class V, class T>
void serialize(Archive & ar, Derived<V,T> &obj, const unsigned int /*version*/) {
ar & boost::serialization::make_nvp("Base1", boost::serialization::base_object<Base<V, int>>(obj) );
ar & boost::serialization::make_nvp("Base2", boost::serialization::base_object<Base<V, std::string>>(obj) );
// does not work
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, int>);
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base<V, std::string>);
ar& BOOST_SERIALIZATION_NVP(obj.t);
}
}} // end namespace
int main() {
Derived<double, int> a(10);
std::ostringstream archive_ostream;
boost::archive::xml_oarchive oa(archive_ostream);
oa << BOOST_SERIALIZATION_NVP(a);
std::cout << archive_ostream.str() << std::endl;
}
我只回答 "bonus" 问题,因为 @sehe 已经回答了主要问题:
为了使用BOOST_SERIALIZATION_BASE_OBJECT_NVP
,serialize
必须是一个成员函数(见nvp.hpp
中的定义)。
以下工作:我必须对 Base 类 进行类型定义才能使宏工作:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
typedef Base<V, int> Base1;
typedef Base<V, std::string> Base2;
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
ar& BOOST_SERIALIZATION_NVP(t);
}