如何为boost映射添加boost归档序列化支持? [英] How do I add boost archive serialization support for boost fusion maps?
问题描述
我想添加功能,以便能够通过boost序列化接口序列化boost融合图。我试过下面的:
#include< iostream>
#include< boost / fusion / container / map.hpp>
#include< boost / fusion / include / map.hpp>
#include< boost / fusion / container / map / map_fwd.hpp>
#include< boost / fusion / include / map_fwd.hpp>
#include< boost / fusion / sequence / intrinsic / at_key.hpp>
#include< boost / fusion / include / at_key.hpp>
#include< boost / fusion / include / io.hpp>
#include< boost / archive / text_iarchive.hpp>
struct fieldOne {};
struct fieldTwo {};
typedef boost :: fusion :: map<
boost :: fusion :: pair< fieldOne,int>,
boost :: fusion :: pair< fieldTwo,double>
> tFusionMap;
int main(){
tFusionMap map;
boost :: archive :: text_iarchive ar(std :: cin);
std :: cin>>地图; / *无编译错误* /
ar&地图; / *编译器错误:* /
return 0;
}
这给出编译器错误:
struct boost :: fusion :: map< boost :: fusion :: pair< fieldOne,int>,
boost :: fusion :: pair< fieldTwo ,double> >'没有名为'serialize'的成员
所以显然我需要自己实现。在搜索网络的指导后,我找到了这些答案
使用BOOST_FUSION_ADAPT_ADT对类的Boost融合序列化
但是,所有这些答案(和许多其他人在网络上)依赖于使用自定义函数调用序列化,例如:
fusion_serialize 。但是,我想以一种我可以调用的方式将地图序列化:
ar& m;
,以便我可以在其他模板函数中使用序列化。
我已尝试将其添加到源文件 namespace boost {
命名空间序列化{
template< class Archive,typename T,std :: size_t num_dims>
void serialize(Archive& ar,T& map,const unsigned int version){
fusion_serialize(ar,map);
}
}
}
因为模板将匹配任何类型,并且如果它不是融合映射,则生成编译错误。我不明白我如何可以修改上述,使 serialize
函数定义只适用于 boost :: fusion :: map
类型。任何建议?
解决方案您可以对任何Fusion地图一般地实现序列化:
namespace boost {namespace serialization {
struct saver {
template< typename Ar,typename Pair&
void operator()(Ar& ar,Pair& data)const
{
ar& data.second;
}
};
template< typename Ar,typename ... TArgs>
void serialize(Ar& ar,boost :: fusion :: map< TArgs ...>& fmap,unsigned / * version * /)
{
using phoenix :: ref ;
using phoenix :: arg_names :: arg1;
static const phoenix :: function< saver>保存 {};
fusion :: for_each(fmap,save(ref(ar),arg1));
}
}}
现在, / p>
#include< boost / archive / text_oarchive.hpp>
#include< iostream>
typedef boost :: fusion :: map<
boost :: fusion :: pair< struct fieldOne,int>,
boost :: fusion :: pair< struct fieldTwo,double>
> tFusionMap;
int main(){
tFusionMap map {42,M_PI};
boost :: archive :: text_oarchive oa(std :: cout);
oa&地图;
}
列印:
22 serialization :: archive 10 0 0 42 3.1415926535897931
反序列化同时实现。
完整性:
#include< boost / fusion / include / map.hpp>
#include< boost / fusion / algorithm.hpp>
#include< boost / phoenix / phoenix.hpp>
#include< boost / phoenix / fusion.hpp>
I'd like to add the functionality to be able to serialize boost fusion maps via the boost serialization interface. I've tried the following:
#include <iostream>
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/container/map/map_fwd.hpp>
#include <boost/fusion/include/map_fwd.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/archive/text_iarchive.hpp>
struct fieldOne {};
struct fieldTwo {};
typedef boost::fusion::map<
boost::fusion::pair<fieldOne, int>,
boost::fusion::pair<fieldTwo, double>
> tFusionMap;
int main() {
tFusionMap map;
boost::archive::text_iarchive ar(std::cin);
std::cin >> map; /* no compile error */
ar & map; /* compiler error: */
return 0;
}
which gives me the compiler error:
struct boost::fusion::map<boost::fusion::pair<fieldOne, int>,
boost::fusion::pair<fieldTwo, double> >’ has no member named ‘serialize’
so apparently I need to implement this myself. After searching the web for some guidance, I found these answers
Boost fusion serialization of a class using BOOST_FUSION_ADAPT_ADT
How to serialize fusion::vector?
however, all of theses answers (and many others on the web) rely on invoking the serialization with a custom function, for example:
fusion_serialize(ar, m);
However, I would like to serialize the map in a way that I can call:
ar & m;
so that I can use the serialization in other template functions. Is there anyway to achieve this?
I've tried adding this to my source file
namespace boost {
namespace serialization {
template<class Archive, typename T, std::size_t num_dims>
void serialize( Archive & ar, T & map, const unsigned int version ) {
fusion_serialize(ar,map);
}
}
}
However, this is too general as the template will match ANY type and generate compile errors if it is not a fusion map. I don't see how I can modify the above so that the serialize
function definition only applies to boost::fusion::map
types. Any suggestions?
解决方案 You can generically implement serialization for any Fusion map:
namespace boost { namespace serialization {
struct saver {
template <typename Ar, typename Pair>
void operator()(Ar& ar, Pair& data) const
{
ar & data.second;
}
};
template <typename Ar, typename... TArgs>
void serialize(Ar& ar, boost::fusion::map<TArgs...>& fmap, unsigned /*version*/)
{
using phoenix::ref;
using phoenix::arg_names::arg1;
static const phoenix::function<saver> save {};
fusion::for_each(fmap, save(ref(ar), arg1));
}
} }
Now, this works:
#include <boost/archive/text_oarchive.hpp>
#include <iostream>
typedef boost::fusion::map<
boost::fusion::pair<struct fieldOne, int>,
boost::fusion::pair<struct fieldTwo, double>
> tFusionMap;
int main() {
tFusionMap map { 42 , M_PI };
boost::archive::text_oarchive oa(std::cout);
oa & map;
}
See it Live On Coliru
Prints:
22 serialization::archive 10 0 0 42 3.1415926535897931
Deserialization is implemented at the same time.
For completeness:
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/phoenix/phoenix.hpp>
#include <boost/phoenix/fusion.hpp>
这篇关于如何为boost映射添加boost归档序列化支持?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!