C++ C++;-boost::任何序列化

C++ C++;-boost::任何序列化,c++,serialization,boost-any,C++,Serialization,Boost Any,据我所知,boost::any占位符不支持序列化(boost::serialization) 有人知道是否有办法序列化自定义的boost::any实体吗 这里的问题很明显:boost::any使用基于模板的占位符存储对象,并使用typeid检查boost::any_cast是否合适 因此,有一个自定义的抽象超类占位符和自定义的基于模板的派生类,它们是通过以下方式创建的: template <T> custom_placeholder : public placeholder {

据我所知,
boost::any
占位符不支持序列化(
boost::serialization

有人知道是否有办法序列化自定义的
boost::any
实体吗

这里的问题很明显:
boost::any
使用基于模板的占位符存储对象,并使用
typeid
检查
boost::any_cast
是否合适

因此,有一个自定义的抽象超类
占位符
和自定义的基于模板的派生类,它们是通过以下方式创建的:

template <T> custom_placeholder : public placeholder {
    virtual std::type_info type() const { return typeid(T); }
    virtual ...
};
模板自定义\u占位符:公共占位符{
虚拟std::type_info type()常量{return typeid(T);}
事实上的
};
显然,即使考虑序列化这些内容,这也会带来一些麻烦。也许有人知道实现这种序列化(当然还有正确的反序列化)的一些技巧


谢谢

这根本不可能,至少对于任意类型来说是不可能的。请注意,也许可以使用一些复杂的代码进行序列化(比如查找any中包含的元素的大小),但是any代码依赖于编译器静态地将any type_代码和正确的类型放入占位符中。在C++中,您不能在反序列化中这样做,因为在编译时,从反序列化中获得的类型(新生成的<代码> Boo::任何< /COD>)都不知道。 最好的解决方案是为要序列化的元素的确切类型构建某种特定的任意类型。然后,您可以为反序列化的实际类型元素有特殊的情况,但是请注意,每个元素类型序列化/反序列化都必须以静态C++代码编写。
警察局。其他一些人建议使用
boost::variant
作为这个特殊类型的表示,它包含您要序列化的确切类型。不过,您需要一种在反序列化时识别确切类型的方法(可能会为变量中的类型分配标识符)。

假设您必须使用
boost::any
,并且无法切换到
variant
,则基于
映射的解决方案可以帮您完成

您必须在运行时使用计划使用的所有类型初始化这样的
映射。当然,你可以使用一些类似于

template <typename T>
struct any_serializer
{
    static string perform(any a)
    {
        T const& x = any_cast<T const&>(a);
        stringstream out;
        out << x;
        return out.str();
    }
};
模板
构造任意_序列化程序
{
静态字符串执行(任意a)
{
T const&x=任何类型(a);
流出来;

out如果您想继续使用boost::any,我不确定,但您可以编写自己的“boost::any”。我将此代码用于代理方法来传递参数

#include <iostream>
#include <boost\smart_ptr\scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <sstream>
class my_placeholder
{
public:
    virtual ~my_placeholder(){}
    my_placeholder(){}
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        // serialize base class information
        //ar & boost::serialization::base_object<bus_stop>(*this);
        //ar & m_placeholder;

    }

};




template<typename T>
class my_derivedplaceholder:
    public my_placeholder
{
    public:
        my_derivedplaceholder()
        {

        }
        my_derivedplaceholder(T &value)
        {
            m_value=value;
        }
    T m_value;

private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        // serialize base class information
        ar & boost::serialization::base_object<my_placeholder>(*this);
        ar & m_value;

    }
};


BOOST_CLASS_EXPORT_GUID(my_derivedplaceholder<int>, "p<int>");


class my_any
{
public:

    my_any()
    {

    }

    template<typename T>
    my_any(const T &value)
    {
        m_placeholder.reset(new my_derivedplaceholder<T>(const_cast<T&>(value)));
    }

    template<typename T>
    void operator=(const T &value)
    {
        m_placeholder.reset(new my_derivedplaceholder<T>(const_cast<T&>(value)));
    }



protected:

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        // serialize base class information
        //ar & boost::serialization::base_object<bus_stop>(*this);
        ar & m_placeholder;

    }

     template<typename T>
    friend    T my_anycast(my_any &val);

    boost::shared_ptr<my_placeholder> m_placeholder;
};

template<typename T>
T my_anycast(my_any &val)
{
    boost::shared_ptr<my_derivedplaceholder<T>> concrete=boost::dynamic_pointer_cast<my_derivedplaceholder<T>>(val.m_placeholder);
    if (concrete.get()==NULL)
        throw std::invalid_argument("Not convertible");

    return concrete->m_value;
}

void main()
{
    my_any m=10;

    int a=my_anycast<int>(m);

    std::cout << a << std::endl;

    std::stringstream ss,ss2;
    boost::archive::text_oarchive oa(ss);

    oa << m;

    boost::archive::text_iarchive ia(ss);

    my_any m2;
    ia >> m2;

    std::cout << my_anycast<int>(m2) << std::endl;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类my_占位符
{
公众:
虚拟~my_占位符(){}
my_占位符(){}
私人:
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
//序列化基类信息
//ar&boost::serialization::base_对象(*this);
//ar&m_占位符;
}
};
模板
类my_derivedplaceholder:
公共my_占位符
{
公众:
我的占位符()
{
}
我的占位符(T和值)
{
m_值=值;
}
T m_值;
私人:
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
//序列化基类信息
ar&boost::serialization::base_对象(*this);
ar&m_值;
}
};
BOOST_CLASS_EXPORT_GUID(my_derivedplaceholder,“p”);
给我的孩子上课
{
公众:
我的_any()
{
}
模板
我的任何(常数和值)
{
重置(新的my_derivedplaceholder(常量转换(值));
}
模板
void运算符=(常量T和值)
{
重置(新的my_derivedplaceholder(常量转换(值));
}
受保护的:
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
//序列化基类信息
//ar&boost::serialization::base_对象(*this);
ar&m_占位符;
}
模板
朋友T我的任何演员(我的任何&val);
boost::shared_ptr m_占位符;
};
模板
T my_anycast(my_any&val)
{
boost::shared_ptr concrete=boost::dynamic_pointer_cast(val.m_占位符);
if(concrete.get()==NULL)
抛出std::无效的_参数(“不可转换”);
返回混凝土->m_值;
}
void main()
{
my_any m=10;
int a=我的任意广播(m);

std::cout不需要创建新类。请尝试使用xany
xany类允许向任何现有功能中添加新方法。顺便说一句,文档中有一个例子完全符合您的要求。

此模式相当棘手,如果您通过网络将这些序列化发送到其他进程或计算机,则无法工作。请注意
&typeid(t)
对于不同的体系结构(甚至可能是程序)会有所不同,所以我不认为这是非常可靠的…响应编辑后:是的,使用自定义类型标识符更有意义。将variant与一组受限类型一起使用也是一个好主意。@Diego:我不认为有问题。映射是程序的本地映射,只是分派各种序列化例程的一种手段。我更关心的是t如果
typeid(t)
是否总是生成可以通过地址进行比较的对象。这可以通过调用
type\u info::before
as
operator@Alexandre:我指的是转移地图(使用typeid作为键)例如,通过网络通道,或被运行在不同体系结构或操作系统中的不同应用程序读取。映射的此键取决于程序,并且