0

下面使用 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_;
};

主文件

#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
4

1 回答 1

0

您可能想尝试更改 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 的序列化支持,那么为什么不直接使用呢?

于 2013-08-02T13:54:56.563 回答