【问题标题】:Boost serialization of template derived class提升模板派生类的序列化
【发布时间】:2015-09-23 20:06:05
【问题描述】:

我有一个模板化的基类 Base 和一个模板化的派生类 Derived,我想对其进行序列化。
下面的简化代码编译并运行,但不序列化基类的数据成员。

#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;
}

演示:Live On Coliru

输出只有:

<?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::uBase::v 的序列化呢?我试过使用BOOST_CLASS_EXPORT(Derived); 没有成功。

额外问题:在这种情况下,我该如何使用宏 BOOST_SERIALIZATION_BASE_OBJECT_NVP

【问题讨论】:

  • 等我有空的时候再看看红利问题

标签: c++ serialization boost polymorphism


【解决方案1】:

您忘记将 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>

Live On Coliru

#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;
}

【讨论】:

  • 谢谢@sehe(再次!:) 的回答,但我不明白。我已经在void serialize(Archive &amp; ar, Derived&lt;V,T&gt; &amp;obj, const unsigned int version)
  • 查看完整示例 :)
  • 哦,谢谢你,我觉得自己很笨......我已经严重复制了我的问题,因为我没有忘记我的真实代码中的ar &amp;......sigh跨度>
【解决方案2】:

我只回答“奖金”问题,因为@sehe 已经回答了主要问题:

为了使用BOOST_SERIALIZATION_BASE_OBJECT_NVPserialize 必须是成员函数(参见nvp.hpp 中的定义)。

以下工作:我必须对基类进行 typedef 才能使宏工作:

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);
}

Live On Coliru

【讨论】:

    猜你喜欢
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    • 2010-11-22
    • 2018-01-22
    • 1970-01-01
    • 2012-05-25
    • 2014-02-04
    相关资源
    最近更新 更多