Serialization 如何使用Boost序列化来序列化std::type_信息?

Serialization 如何使用Boost序列化来序列化std::type_信息?,serialization,boost,rtti,Serialization,Boost,Rtti,我想记录变量的std::type_info,以便在加载时能够重新创建适当的类型变量 保存将如下所示: friend class boost::serialization::access; template<class Archive> void save(Archive & ar, const unsigned int version) const { ... ar & BOOST_SERIALIZATION_NVP(typeid(value));

我想记录变量的
std::type_info
,以便在加载时能够重新创建适当的类型变量

保存将如下所示:

friend class boost::serialization::access;
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
    ...
    ar & BOOST_SERIALIZATION_NVP(typeid(value)); 
    ar & BOOST_SERIALIZATION_NVP(value);
    ...
}
friend类boost::serialization::access;
模板
无效保存(存档和应收账款,常量未签名整数版本)常量
{
...
ar&BOOST_序列化_NVP(类型ID(值));
ar&BOOST\U序列化\U NVP(值);
...
}
加载将如下所示:

template<class Archive>
void load(Archive & ar, const unsigned int version)
{
    ...
    std::type_info currentType;
    ar & BOOST_SERIALIZATION_NVP(currentType);

    if(currentType.name() == typeid(std::string).name())
    {
        std::string value;
        ar & BOOST_SERIALIZATION_NVP(value);

        //this next line is why I need to read back the type
        someObject.setValue<std::string>(value);
    }
    ... //else if for all other types
}
模板
无效加载(存档和应收账款,常量未签名整数版本)
{
...
std::type_info currentType;
ar&BOOST\U序列化\U NVP(当前类型);
如果(currentType.name()==typeid(std::string).name())
{
std::字符串值;
ar&BOOST\U序列化\U NVP(值);
//下一行就是我需要读回类型的原因
setValue(value);
}
…//如果用于所有其他类型,则为else
}

或者,如果你对解决这个问题有任何其他想法,我愿意接受建议。我觉得我这样做是错误的。

我不知道这是否正是您所寻找的,而且这肯定是一种不同于您目前所采用的方法,因此。。。但在过去,我通过创建类型层次结构,然后使用Boost.Serialization自动序列化/反序列化多态类型指针的功能,实现了类似的目标。这样做的好处是不必在代码中使用任何RTTI(库可能在幕后进行RTTI,我不确定),但也有一些缺点

首先,在我看来,这无疑会使代码更加复杂。您可能正在处理代码中的类型,这些类型您无法轻松修改或工作到层次结构中。您也可能不愿意承受多态性和堆分配带来的(相对较小的)性能影响

这里有一个或多或少完整的例子。visitor模式在这里很有用,因为您可能只需要一个非常薄的包装器来包装可能没有任何共同点的现有类型:

#include <boost/serialization/export.hpp>

class Visitor;

class Base
{
public:
    virtual ~Base() { }
    virtual void accept(const Visitor & v) = 0;

protected:
    friend class boost::serialization::access;
    template <typename Archive>
    void serialize(Archive & ar, const unsigned int version)
    { }
};

/* specialization for one set of types */
class Type1 : public Base
{
public:
    virtual ~Type1() { }
    virtual void accept(const Visitor & v) { ... }

protected:
    friend class boost::serialization::access;
    template <typename Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<Base>(*this);
        ar & m_dataType1;
        ar & m_dataType2;
        //etc...
    }
    //member data follows...
};

/* specialization for some other set of types */
class Type2 : public Base
{
public:
    virtual ~Type2() { }
    virtual void accept(const Visitor & v) { ... }

protected:
    friend class boost::serialization::access;
    template <typename Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<Base>(*this);
        ar & m_dataType1;
        ar & m_dataType2;
        //etc...
    }
};

BOOST_CLASS_EXPORT_GUID(Type1, "Type1")
BOOST_CLASS_EXPORT_GUID(Type2, "Type2")
以下问题和答案也可能有用:

希望这有帮助


编辑:修复了我与Boost文档的链接…

非常感谢您的回复!这个方法肯定会消除我对rtti的依赖,这很好,但它会添加一些我并不想添加的新类。我现在有8种不同的类型,以后可能会更多。我现在所做的不是序列化std::type_info,而是序列化std::type_info.name(),然后在反序列化时比较字符串。这不是最漂亮的解决方案,但我认为它能满足我的要求。
boost::shared_ptr<Base> p;
...
p.reset(new Type1(...));
archive << p;
p.reset(new Type2(...));
archive << p;
...
archive >> p; //p now points to a Type1
archive >> p; //p now points to a Type2