0

g++4.8.1 とブースト 1.55.0 を使用して Linux ubuntu で C++ コードをコンパイルしています。私のプログラムは、unsigned long long arrayであるメンバーテーブルを持つクラス A を使用します。同じクラスには、単純な int である他のメンバーがあります。ブーストを使用してデータをシリアル化しています。Aのテーブル以外のすべてをシリアル化すると、私のコードは機能し、すべて正常にコンパイルされます。

ただし、 tableをシリアライズしようとするとコンパイルされません。次のエラーが表示されます。

/usr/local/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’:
/usr/local/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’:
/usr/local/include/boost/serialization/serialization.hpp:69:69:   required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/serialization/serialization.hpp:128:27:   required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/archive/detail/oserializer.hpp:152:5:   required from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/archive/detail/oserializer.hpp:101:1:   required from ‘class boost::archive::detail::oserializer<boost::archive::text_oarchive, long long unsigned int>’
/usr/local/include/boost/archive/detail/oserializer.hpp:214:5:   required from ‘boost::archive::detail::pointer_oserializer<Archive, T>::pointer_oserializer() [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/serialization/singleton.hpp:106:7:   [ skipping 95 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/boost/archive/detail/oserializer.hpp:314:44:   required from ‘static void boost::archive::detail::save_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = Metapop; Archive = boost::archive::text_oarchive]’
/usr/local/include/boost/archive/detail/oserializer.hpp:525:24:   required from ‘void boost::archive::save(Archive&, T&) [with Archive = boost::archive::text_oarchive; T = Metapop]’
/usr/local/include/boost/archive/detail/common_oarchive.hpp:69:40:   required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = Metapop; Archive = boost::archive::text_oarchive]’
/usr/local/include/boost/archive/basic_text_oarchive.hpp:80:9:   required from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = Metapop; Archive = boost::archive::text_oarchive]’
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:63:9:   required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = Metapop; Archive = boost::archive::text_oarchive]’ 
simulation.cpp:1403:9:   required from here
/usr/local/include/boost/serialization/access.hpp:118:9: error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘long long unsigned int’
     t.serialize(ar, file_version);
     ^

ベクトルまたは/および他のデータ型を使用すると機能することを読んだことがあります。ただし、(速度のために) unsigned long long の生の配列を使用することが重要です。何か案が ?

ありがとうございます!

4

1 に答える 1

0

配列のシリアルunsigned long long化は、gcc 4.7.2 とブースト 1.49、gcc 4.2.1 とブースト 1.55、clang 3.4 とブースト 1.55 を使用して機能します。

#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/version.hpp>

struct Foo {
   unsigned long long bar[3];

   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/) {
      ar & bar;
   }
};

std::ostream& operator<<(std::ostream& os, const Foo& foo) {
   return os << foo.bar[0] << ' ' << foo.bar[1] << ' ' << foo.bar[2];
}

int main() {
   std::cout << "Boost version " << BOOST_LIB_VERSION << '\n';

   Foo before;
   before.bar[0] = 0;
   before.bar[1] = 1;
   before.bar[2] = 2;

   std::cout << "before: " << before << '\n';

   std::ostringstream os;
   {
      boost::archive::text_oarchive oa(os);
      oa << before;
   }

   Foo after;
   {
      std::istringstream is(os.str());
      boost::archive::text_iarchive ia(is);
      ia >> after;
   }

   std::cout << "after: " << after << '\n';

   return 0;
}

Coliruでブースト 1.55 を使用した gcc 4.8も動作します。

割り当てられた配列へのポインターを使用している場合、それが問題だと思います。ベア ポインターをプリミティブにシリアル化できるとは思えません。ベア ポインターをプリミティブの配列にシリアル化できないと確信しています。これは、ポインターが指している要素の数をシリアル化で知る方法がないためです。

割り当てられた配列に対してa を使用しstd::vectorます。そうすることで速度が低下することはないからです。ただし、本当に独自の配列を割り当てたい場合は、次のようにboost::serialization::make_array()ラッパーでシリアル化できます。

#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/array.hpp>

struct Foo {
   size_t dataSize;
   unsigned long long *data;

   Foo()
      : dataSize(3)
      , data(new unsigned long long[dataSize]) {
   }

   ~Foo() {
      delete[] data;
   }

   // TODO: Production code should disallow default copy constructor
   // and assignment operator.

   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/) {
      ar & dataSize;
      ar & boost::serialization::make_array(data, dataSize);
   }
};

int main() {
   Foo foo;
   foo.data[0] = 0;
   foo.data[1] = 1;
   foo.data[2] = 2;

   boost::archive::text_oarchive oa(std::cout);
   oa << foo;

   return 0;
}

この質問はまったく問題ではなかったことが判明しましたが、本質的には生のC配列のブーストシリアライゼーション、デシリアライゼーションのunsigned long long複製です。

于 2014-05-24T16:48:09.580 に答える