Boost mpl::list 变体序列化 check_const_loading() 编译错误

Posted

技术标签:

【中文标题】Boost mpl::list 变体序列化 check_const_loading() 编译错误【英文标题】:Boost mpl::list variant serialization check_const_loading() compile error 【发布时间】:2013-07-16 11:44:16 【问题描述】:

下面使用 mpl::list 来初始化一个 boost 变体。然后它序列化变体。它可以编译并在保存但不加载时正常工作。编译甚至加载失败。有谁知道问题是什么? 谢谢

属性.h

#include <string>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

template <class T>
class Attribute

public:
      Attribute() 
      Attribute( const std::string& name, const T& t ) : name_( name ), t_( t ) 

      std::string name() const  return name_; 
      const T& get() const  return t_; 
      void set( const T& t )  t_ = t; 

      friend class boost::serialization::access;
      template<class Archive>
      void serialize( Archive& ar, const unsigned int version )
      
            ar & BOOST_SERIALIZATION_NVP( name_ );
            ar & BOOST_SERIALIZATION_NVP( t_ );
      

private:
      std::string name_;
      T t_;
;

AttributeAny.h

#include <boost/variant.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/variant/apply_visitor.hpp>

template <class T>
class AttributeAny

public:
      typedef typename boost::make_variant_over<T>::type Type;

      AttributeAny() 
      AttributeAny( const Type& t ) : t_( t )  

private:
      template <class Archive>
      class SerializeVisitor : public boost::static_visitor<>
      
      public:
            SerializeVisitor( Archive& ar ) : ar_( ar ) 
            template <typename U>
            void operator()( const U& t ) const
            
                  ar_ & BOOST_SERIALIZATION_NVP( t );
            
      private:
            Archive& ar_;
      ;

public:

      friend class boost::serialization::access;
      template<class Archive>
      void serialize( Archive& ar, const unsigned int version )
      
            boost::apply_visitor( SerializeVisitor<Archive>( ar ), t_ );
      

private:
      Type t_;
;

main.cpp

#include <iostream>
#include <sstream>
#include <boost/mpl/list.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "mylib/Attribute.h"
#include "mylib/AttributeAny.h"


using namespace std;

class A

public:
      A() 
      A( const std::string& name ) : name_( name ) 
      std::string name() const  return name_; 

      friend class boost::serialization::access;
      template<class Archive>
      void serialize( Archive& ar, const unsigned int version )
      
            ar & BOOST_SERIALIZATION_NVP( name_ );
      

private:
      std::string name_;
;

using namespace std;

typedef AttributeAny<boost::mpl::list<
//            Attribute<double>
//          , Attribute<long>
            A // this, doesn't even work, on serialize load
> > Any;

int main()


      A a( "a" );
      Any any( a );
      Any any1( a );

      std::stringstream ss;
      boost::archive::xml_oarchive oa( ss );
      oa << BOOST_SERIALIZATION_NVP( a );
      cout << ss.str() << endl;

      // these 2 lines below cause compilation error
      // serialize save work just fine...
      boost::archive::xml_iarchive ia( ss );
      ia >> BOOST_SERIALIZATION_NVP( any1 );

      return 0;

编译错误:

/usr/local/boost/boost_1_48_0/include/boost/archive/detail/check.hpp: In function ‘void boost::archive::detail::check_const_loading() [with T = const A]’:
/usr/local/boost/boost_1_48_0/include/boost/archive/detail/iserializer.hpp:577:   instantiated from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::xml_iarchive, T = const A]’
/usr/local/boost/boost_1_48_0/include/boost/archive/detail/common_iarchive.hpp:66:   instantiated from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = const A, Archive = boost::archive::xml_iarchive]’
/usr/local/boost/boost_1_48_0/include/boost/archive/basic_xml_iarchive.hpp:86:   instantiated from ‘void boost::archive::basic_xml_iarchive<Archive>::load_override(const boost::serialization::nvp<T>&, int) [with T = const A, Archive = boost::archive::xml_iarchive]’
/usr/local/boost/boost_1_48_0/include/boost/archive/xml_iarchive.hpp:93:   instantiated from ‘void boost::archive::xml_iarchive_impl<Archive>::load_override(T&, int) [with T = const boost::serialization::nvp<const A>, Archive = boost::archive::xml_iarchive]’
/usr/local/boost/boost_1_48_0/include/boost/archive/detail/interface_iarchive.hpp:60:   instantiated from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = const boost::serialization::nvp<const A>, Archive = boost::archive::xml_iarchive]’
/usr/local/boost/boost_1_48_0/include/boost/archive/detail/interface_iarchive.hpp:67:   instantiated from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = const boost::serialization::nvp<const A>, Archive = boost::archive::xml_iarchive]’
~/ws/mylib/AttributeAny.h:34:   instantiated from ‘void AttributeAny<T>::SerializeVisitor<Archive>::operator()(const U&) const [with U = A, Archive = boost::archive::xml_iarchive, T = boost::mpl::list<A, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>]’
/usr/local/boost/boost_1_48_0/include/boost/variant/variant.hpp:858:   instantiated from ‘typename Visitor::result_type boost::detail::variant::invoke_visitor<Visitor>::internal_visit(T&, int) [with T = A, Visitor = const AttributeAny<boost::mpl::list<A, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >::SerializeVisitor<boost::archive::xml_iarchive>]’
...
../src/test_mylib.cpp:61:   instantiated from here

/usr/local/boost/boost_1_48_0/include/boost/archive/detail/check.hpp:162: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>‘
/usr/local/boost/boost_1_48_0/include/boost/archive/detail/check.hpp:162: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>‘
make: *** [src/test_mylib.o] Error 1

【问题讨论】:

【参考方案1】:

您可能想尝试从

更改 SerializeVisitor 上的函数运算符
template <typename U>
void operator()( const U& t ) const

template <typename U>
void operator()( U& t ) const

当然,boost 已经在 boost/serialization/variant.hpp 中包含了对 boost::variant 的序列化支持,那么为什么不直接使用呢?

【讨论】:

以上是关于Boost mpl::list 变体序列化 check_const_loading() 编译错误的主要内容,如果未能解决你的问题,请参考以下文章

强大的 boost::variant 序列化

C++ Boost 变体错误

boost::unordered_map 中以结构为键的 boost 变体

Boost::variant 与引用相同变体的对象

Boost:创建一个返回变体的函数

构造一个包含变体类型索引中第 n 个类型值的 boost 变体?