我正在编译一个c++代码在linux ubuntu与g++4.8.1和boost 1.55.0。我的程序使用一个类a,它有一个成员表,它是一个无符号长数组。同一个类还有其他简单的int型成员。我使用boost来序列化我的数据。如果我在a中序列化除表之外的所有表,那么我的代码工作和编译都很好。
然而,如果我试图序列化表,它不会编译。我得到以下错误:
/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的原始数组是至关重要的。你知道吗?
非常感谢你的帮助
序列化unsigned long long
数组适用于我使用gcc 4.7.2与boost 1.49, gcc 4.2.1与boost 1.55, clang 3.4与boost 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;
}
这是gcc 4.8与boost 1.55在Coliru上,也工作。
如果你使用一个指针分配数组,那么我认为这是你的问题。我不相信你可以序列化一个指向原语的裸指针,而且我确信你也不能序列化一个指向原语数组的裸指针,因为序列化无法知道一个指针指向多少个元素。
我将在分配的数组上使用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;
}
事实证明,这个问题根本不是关于unsigned long long
的,而本质上是对原始C数组的boost序列化和反序列化的重复。