我正在编写一个库,用于处理用户定义类型的存储和序列化。用户定义的类型必须是可自行序列化的。
但是,库使用模板来创建用户类型的容器。我不知道如何通过模板将容器类型导出到boost :: serialization。我能做到的唯一方法是强制每个容器类型的库的用户BOOST_CLASS_EXPORT_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;
}
答案 0 :(得分:0)
也许是这样的:
#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) \
/**/
它可能会对它进行一些额外的调整。当然,它可能会假设user_type也已导出。但是,它会减少组合维度,你需要的只是每个类一个导出和每个类模板一个导出,而不是每个模板实例化一个导出(类的数量X类模板的数量)。
这可能是应该向负责Boost.Serialization库的人询问/要求/提议的事情(我想这将是Robert Ramey)。