Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Boost序列化注册用户提供的派生类型_C++_Serialization_Boost_Export_Boost Serialization - Fatal编程技术网

C++ 使用Boost序列化注册用户提供的派生类型

C++ 使用Boost序列化注册用户提供的派生类型,c++,serialization,boost,export,boost-serialization,C++,Serialization,Boost,Export,Boost Serialization,我正在编写一个库来处理存储和序列化用户定义的类型。用户定义的类型本身必须是可序列化的 但是,库使用模板创建用户类型的容器。我不知道如何通过模板将容器类型导出到boost::serialization。我能做的唯一方法是强制库的用户对每个容器类型增强\u CLASS\u EXPORT\u GUID() 我试图通过查看boost/serialization/export.hpp来解包宏,但它有点复杂。。。是否有方法将类导出为模板实例化的一部分?还是另一种编写库以轻松序列化用户定义类型的容器的方法 #

我正在编写一个库来处理存储和序列化用户定义的类型。用户定义的类型本身必须是可序列化的

但是,库使用模板创建用户类型的容器。我不知道如何通过模板将容器类型导出到boost::serialization。我能做的唯一方法是强制库的用户对每个容器类型增强\u CLASS\u EXPORT\u GUID()

我试图通过查看boost/serialization/export.hpp来解包宏,但它有点复杂。。。是否有方法将类导出为模板实例化的一部分?还是另一种编写库以轻松序列化用户定义类型的容器的方法

#include <iostream>
#include <vector>

#include <boost/foreach.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>

#include <boost/archive/text_oarchive.hpp>

//////////////////////////////////////////////////////////////////////////////
// Example code that would reside in the library
//////////////////////////////////////////////////////////////////////////////

struct type_container_base {
private:
    virtual void make_abstract() const {}
    friend class ::boost::serialization::access;
    template <typename ARCHIVE>
    void serialize(ARCHIVE &, const unsigned int) {}    
};

BOOST_SERIALIZATION_ASSUME_ABSTRACT(type_container_base)

template <typename USER_TYPE>
struct type_container : type_container_base {
    void add(const USER_TYPE& d) { _vector.push_back(d); }
private:
    std::vector<USER_TYPE> _vector;
    friend class ::boost::serialization::access;
    template <typename ARCHIVE>
    void serialize(ARCHIVE & ar, const unsigned int) {
        ar & ::boost::serialization::base_object<type_container_base>(*this);
        ar & _vector;
    }
};

//////////////////////////////////////////////////////////////////////////////
// Example user code that would use the library
//////////////////////////////////////////////////////////////////////////////

struct user_type {
    user_type(int i) : _val(i) {}
private:
    int _val;
    friend class ::boost::serialization::access;
    template <typename ARCHIVE>
    void serialize(ARCHIVE & ar, const unsigned int) {
        ar & _val;
    }
};

// *** Is there a better way than forcing the user to do this for every
// *** user_type they want to use with the library?
BOOST_CLASS_EXPORT_GUID(type_container<user_type>, "type_container<user_type>")

int main() {
    std::vector<type_container_base*> containers;
    type_container<user_type>* tc = new type_container<user_type>();
    tc->add(user_type(7));
    tc->add(user_type(42));
    tc->add(user_type(1776));
    containers.push_back(tc);
    {
        boost::archive::text_oarchive ar(std::cout);
        const std::size_t size = containers.size();
        ar << size;
        BOOST_FOREACH(type_container_base* p, containers)
            ar << p;
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//////////////////////////////////////////////////////////////////////////////
//将驻留在库中的示例代码
//////////////////////////////////////////////////////////////////////////////
结构类型\容器\基础{
私人:
虚空make_abstract()const{}
好友类::boost::序列化::access;
模板
void序列化(存档&,常量unsigned int){}
};
BOOST\u序列化\u假定\u抽象(类型\u容器\u基)
模板
结构类型\u容器:类型\u容器\u基{
void add(const USER_TYPE&d){_vector.push_back(d)}
私人:
std::vector\u vector;
好友类::boost::序列化::access;
模板
无效序列化(存档和ar,常量unsigned int){
ar&:::boost::serialization::base_对象(*this);
ar&u向量;
}
};
//////////////////////////////////////////////////////////////////////////////
//将使用库的示例用户代码
//////////////////////////////////////////////////////////////////////////////
结构用户类型{
用户类型(inti):\u val(i){}
私人:
国际价值;
好友类::boost::序列化::access;
模板
无效序列化(存档和ar,常量unsigned int){
ar&u-val;
}
};
//***有没有比强迫用户每次都这样做更好的方法
//***要与库一起使用的用户类型?
BOOST\u CLASS\u EXPORT\u GUID(type\u container,“type\u container”)
int main(){
std::载体容器;
type_container*tc=新的type_container();
tc->add(用户类型(7));
tc->add(用户类型(42));
tc->add(用户类型(1776));
集装箱。推回(tc);
{
boost::archive::text\u oarchive ar(std::cout);
const std::size_t size=containers.size();

ar可能是这样的:

#define BOOST_CLASS_TEMPLATE_EXPORT_IMPLEMENT(T)             \
    namespace boost {                                        \
    namespace archive {                                      \
    namespace detail {                                       \
    namespace {                                              \
    template<typename U>                                     \
    struct init_guid< T<U> > {                               \
        static guid_initializer< T<U> > const & g;           \
    };                                                       \
    template<typename U>                                     \
    guid_initializer< T<U> > const & init_guid< T<U> >::g =  \
        ::boost::serialization::singleton<                   \
            guid_initializer< T<U> >                         \
        >::get_mutable_instance().export_guid();             \
    }}}}                                                     \
/**/

#define BOOST_CLASS_TEMPLATE_EXPORT_KEY2(T, K) \
namespace boost {                              \
namespace serialization {                      \
template<typename U>                           \
struct guid_defined< T<U> > : boost::mpl::true_ {}; \
template<typename U>                           \
inline const char * guid< T<U> >(){            \
    return K + "<" + guid<U>() + ">"; //this doesn't work, I know! \
}                                              \
} /* serialization */                          \
} /* boost */                                  \
/**/

#define BOOST_CLASS_TEMPLATE_EXPORT_KEY(T)                             \
    BOOST_CLASS_TEMPLATE_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T))                                                         \
/**/

#define BOOST_CLASS_TEMPLATE_EXPORT_GUID(T, K)                         \
BOOST_CLASS_TEMPLATE_EXPORT_KEY2(T, K)                                 \
BOOST_CLASS_TEMPLATE_EXPORT_IMPLEMENT(T)                               \
/**/
\define BOOST\u CLASS\u TEMPLATE\u EXPORT\u IMPLEMENT(T)\
名称空间提升{\
命名空间存档{\
名称空间详细信息{\
命名空间{\
模板\
结构初始化guid{\
静态guid_初始值设定项const&g\
};                                                       \
模板\
guid\u初始值设定项常量和初始值guid::g=\
::boost::序列化::单例<\
guid\u初始值设定项\
>::获取可变实例()。导出guid()\
}}}}                                                     \
/**/
#定义BOOST\u类\u模板\u导出\u键2(T,K)\
名称空间提升{\
命名空间序列化{\
模板\
结构guid_定义:boost::mpl::true{}\
模板\
内联常量字符*guid(){\
返回K+“”;//我知道这不起作用\
}                                              \
}/*序列化*/\
}/*boost*/\
/**/
#定义增强类模板导出密钥(T)\
BOOST_CLASS_模板_导出_键2(T,BOOST_PP_STRINGIZE(T))\
/**/
#定义BOOST\u类\u模板\u导出\u GUID(T,K)\
增强类模板导出键2(T,K)\
增强类模板导出工具(T)\
/**/
它可能需要一些额外的调整。当然,它可能会假设用户类型也已导出。但是,它将减少组合维度,您只需要每个类导出一次,每个类模板导出一次,而不是每个模板实例化导出一次(类数X类模板数)


这可能是应该向负责Boost.Serialization库的人询问/请求/建议的事情(我想那应该是Robert Ramey).

Hmm…可能有一些问题。只是澄清一下,我的问题不是导出容器类型,而是我无法导出一个参数未知的模板的特殊化类型。这是因为BOOST_…宏在命名空间范围内操作,所以我需要用户处理其类型的导出(和/或相关的容器类型)。而我希望库能够处理它,可以直接插入序列化库。