Here ist der Boost-Code, den Sie, speziell dieser Test unzureichend umgehen möchten:
if(static_cast<std::size_t>(count) > current_count)
boost::serialization::throw_exception(
archive::archive_exception(
boost::archive::archive_exception::array_size_too_short
)
);
Eine Abhilfe ist, ersetzen Sie Ihre eigene Serialisierung für std::array
. Dies ist am einfachsten, wenn Sie vermeiden können, dass die Kopfzeile boost/serialization/array.hpp
für jede Übersetzungseinheit, die Sie serialisieren, enthält. Es ist immer noch möglich, wenn Sie diese Header-Datei benötigen (zB gewöhnlichen Arrays serialisiert) - den Trick, um die Boost templated function passend zu vermeiden:
template <class Archive, class T, std::size_t N>
void serialize(Archive& ar, std::array<T,N>& a, const unsigned int /* version */)
...
Eine Möglichkeit, dies zu tun, ist explizit Ihren Elementtyp angeben:
typedef int MyArrayElementType;
namespace std {
template<class Archive, size_t N>
void serialize(Archive& ar, std::array<MyArrayElementType, N>& a, const unsigned int version)
...
Hier ist eine Anpassung Ihrer MCVE:
#include <iostream>
#include <sstream>
#include <array>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
// Supply your element type here.
typedef int MyArrayElementType;
namespace std {
template<class Archive, size_t N>
void serialize(Archive& ar, std::array<MyArrayElementType, N>& a, const unsigned int version) {
boost::serialization::split_free(ar, a, version);
}
template<class Archive, size_t N>
void save(Archive& ar, const std::array<MyArrayElementType, N>& a, const unsigned int version) {
// Adapted code from oserializer.hpp save_array_type::invoke().
boost::serialization::collection_size_type count(N);
ar << BOOST_SERIALIZATION_NVP(count);
ar << boost::serialization::make_array(static_cast<MyArrayElementType const*>(&a[0]), count);
}
template<class Archive, size_t N>
void load(Archive& ar, std::array<MyArrayElementType, N>& a, const unsigned int version) {
// Adapted code from iserializer.hpp load_array_type::invoke().
boost::serialization::collection_size_type count;
ar >> BOOST_SERIALIZATION_NVP(count);
if(static_cast<std::size_t>(count) != N)
boost::serialization::throw_exception(
std::runtime_error("std::array size mismatch")
);
ar >> boost::serialization::make_array(static_cast<MyArrayElementType*>(&a[0]), count);
}
}
int main()
{
const size_t arr1_size = 3, arr2_size = 4;
std::stringstream ss;
// save
std::array<int, arr1_size> arr1;
boost::archive::text_oarchive oar(ss, boost::archive::no_header);
oar & arr1;
// load
std::array<int, arr2_size> arr2;
boost::archive::text_iarchive iar(ss, boost::archive::no_header);
iar & arr2; // throw on size inequality, please
}
Live on CoLiRu
Dies verwendet dieselbe Array-Serialisierungsmaschinerie wie die integrierte Serialisierung, daher sollte sie genau die gleiche Leistung haben. Wenn Sie boost/serialization/array.hpp
entfernen können, können Sie stattdessen MyArrayElementType
in ein Vorlagenargument ändern.
Ich denke, Sie müssen entweder die Größe des Arrays vor dem Array selbst serialisieren und dann auf Deserialisierung überprüfen oder zu einem Vektor wechseln (wie viel Leistungsverlust sprechen wir hier wirklich?) –
@RichardHodges Thanks für den dritten Weg wären die Elemente vom Typ abgeleitet von "boost :: bimap" - nicht beweglich, so scheint es. – LogicStuff