如何为boost映射添加boost归档序列化支持? [英] How do I add boost archive serialization support for boost fusion maps?

查看:231
本文介绍了如何为boost映射添加boost归档序列化支持?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加功能,以便能够通过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 :: vector?



但是,所有这些答案(和许多其他人在网络上)依赖于使用自定义函数调用序列化,例如:

  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&地图;
}

查看 Live on Coliru



列印:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆