Boost serialize boost::array failed

I’m trying the examples of this link: https://theboostcpplibraries.com/boost.serialization-wrappers

But the example that directly serialize boost::array compile failed:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <sstream>

using namespace boost::archive;

std::stringstream ss;

void save()
{
  text_oarchive oa{ss};
  boost::array<int, 3> a{{0, 1, 2}};
  oa << a;
}

void load()
{
  text_iarchive ia{ss};
  boost::array<int, 3> a;
  ia >> a;
  std::cout << a[0] << ", " << a[1] << ", " << a[2] << 'n';
}

int main()
{
  save();
  load();
}

A part of error code shows like:

In files included from /usr/local/lib/libboost1.65.1/include/boost/serialization/extended_type_info_typeid.hpp:37:0,
/usr/local/lib/libboost1.65.1/include/boost/archive/detail/oserialzer.hpp:39,
/usr/local/lib/libboost1.65.1/include/boost/archive/detail/interface_oarchive.hpp:23,
/usr/local/lib/libboost1.65.1/include/boost/archive/detail/common_oarchive.hpp:22,
/usr/local/lib/libboost1.65.1/include/boost/archive/basic_text_oarchive.hpp:29,
/usr/local/lib/libboost1.65.1/include/boost/archive/text_oarchive.hpp:31,
from test.cpp:1:

/usr/local/lib/libboost1.65.1/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 = boost_array<int, 3ul>]':
/usr/local/lib/libboost1.65.1/include/boost/serialization/serialization.hpp:68:69: required from 'void boost:serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = boost_array<int, 3ul>]'
/usr/local/lib/libboost1.65.1/include/boost/serialization/serialization.hpp:126:23: required from 'void boost:serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = boost_array<int, 3ul>]'
..................
test.cpp:15:9: required from here
/usr/include/boost/serialization/access.hpp:116:9: error: 'class boost::array<int, 3ul>' has no member named serialize'
   t.serialize(ar, file_version);
   ^

My system config: Ubuntu 18.04 + Boost 1.65.1

I’ve been tried my manually installed boost 1.65.1 in the lib path /usr/local/lib/libboost1.65.1/ and system installed boost 1.65.1 in the lib path /usr/lib/x86_64-linux-gnu/. Unfortunately, both of the libraries compiled failed as the same error.

But if the boost array use wrapper function boost::serialization::make_array(), It will compile OK and works.

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

using namespace boost::archive;

std::stringstream ss;

void save()
{
  text_oarchive oa{ss};
  std::array<int, 3> a{{0, 1, 2}};
  oa << boost::serialization::make_array(a.data(), a.size());
}

void load()
{
  text_iarchive ia{ss};
  std::array<int, 3> a;
  ia >> boost::serialization::make_array(a.data(), a.size());
  std::cout << a[0] << ", " << a[1] << ", " << a[2] << 'n';
}

int main()
{
  save();
  load();
}

or I manually change the line

oa << a;

and

ia >> a;

to

oa << boost::serialization::make_array(a.data(), a.size());

and

ia >> boost::serialization::make_array(a.data(), a.size());

It will compile OK too.

Answer

The global variable ss raises red flags. Sharing in that way may have unintended consequences:

  • for one, residu content maybe remain
  • more subtly, there might not be a flush when required.

Besides that, it looks like you’re missing the include for array serialization:

#include <boost/serialization/boost_array.hpp>

Adding it makes it compile, but let’s also fix the function interface to remove the global:

Live On Coliru

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/array.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/boost_array.hpp>
#include <iostream>
#include <sstream>

std::string save()
{
    std::ostringstream            ss;
    boost::archive::text_oarchive oa{ss};

    boost::array<int, 3> a{{0, 1, 2}};
    oa << a;

    return std::move(ss).str();
}

void load(std::string text)
{
    std::istringstream ss(std::move(text));
    boost::archive::text_iarchive ia{ss};

    boost::array<int, 3> a;
    ia >> a;
    std::cout << a[0] << ", " << a[1] << ", " << a[2] << 'n';
}

int main()
{
    auto text = save();
    load(text);
}

Prints

0, 1, 2