Без подписи длинная длинная сериализация в boost

Я собираю код C ++ на Linux Ubuntu с G ++ 4.8.1 и Boost 1.55.0.
Моя программа использует класс A, в котором есть член Таблица который является беззнаковый длинный длинный массив. В этом же классе есть другие члены, которые являются простыми 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/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);
^

Я прочитал aroud, что если бы я использовал векторы и / или другой тип данных, это работало бы. Однако для меня очень важно (для скорости) использовать необработанный массив unsigned long long. Любая идея ?

Большое спасибо за помощь!

0

Решение

Сериализация 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 с бустом 1.55 на колиру, тоже работает.

Если вы используете указатель на выделенный массив, то я думаю, что это ваша проблема. Я не верю, что вы можете сериализовать пустой указатель на примитив, и я уверен, что вы не можете сериализовать пустой указатель на массив примитивов, потому что у сериализации нет способа узнать, на сколько элементов указывает указатель.

Я бы использовал 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.

0

Другие решения


По вопросам рекламы [email protected]