C++ 使用Boost序列化注册用户提供的派生类型
我正在编写一个库来处理存储和序列化用户定义的类型。用户定义的类型本身必须是可序列化的 但是,库使用模板创建用户类型的容器。我不知道如何通过模板将容器类型导出到boost::serialization。我能做的唯一方法是强制库的用户对每个容器类型增强\u CLASS\u EXPORT\u GUID() 我试图通过查看boost/serialization/export.hpp来解包宏,但它有点复杂。。。是否有方法将类导出为模板实例化的一部分?还是另一种编写库以轻松序列化用户定义类型的容器的方法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来解包宏,但它有点复杂。。。是否有方法将类导出为模板实例化的一部分?还是另一种编写库以轻松序列化用户定义类型的容器的方法 #
#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_…宏在命名空间范围内操作,所以我需要用户处理其类型的导出(和/或相关的容器类型)。而我希望库能够处理它,可以直接插入序列化库。