【问题标题】:Boost serialize boost::array failedBoost 序列化 boost::array 失败
【发布时间】:2021-09-14 11:43:56
【问题描述】:

我正在尝试此链接的示例:https://theboostcpplibraries.com/boost.serialization-wrappers

但是直接序列化 boost::array 的例子编译失败:

#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();
}

部分错误代码显示如下:

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);
   ^

我的系统配置: Ubuntu 18.04 + Boost 1.65.1

我已经尝试在 lib 路径 /usr/local/lib/libboost1.65.1/ 中手动安装 boost 1.65.1,并且系统在 lib 路径 /usr/lib/x86_64-linux- 中安装了 boost 1.65.1 GNU/. 不幸的是,编译的两个库都因相同的错误而失败。

但是如果 boost 数组使用包装函数 boost::serialization::make_array(), 它将编译好并工作。

#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();
}

或者我手动换行

oa << a;

ia >> a;

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

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

它也可以编译。

【问题讨论】:

  • make_array 包装器旨在包装 /any/ 连续的元素数组,但 boost::array 支持旨在让您不需要它。

标签: c++ boost


【解决方案1】:

全局变量ss 引发了危险信号。以这种方式分享可能会产生意想不到的后果:

  • 一方面,残留内容可能会保留
  • 更微妙的是,在需要时可能没有冲洗。

除此之外,您似乎缺少用于数组序列化的包含:

#include <boost/serialization/boost_array.hpp>

添加makes it compile,但我们还要修复函数接口以移除全局:

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);
}

打印

0, 1, 2

【讨论】:

  • 谢谢你!我已经尝试了您的解决方案并添加了 ,但遗憾的是它仍然是相同的错误。如果我使用方法 make_array,它可以编译。所以我猜我的编译环境有问题。
  • 我找到了解决这个问题的“技巧”:根据第 116 行:boost.org/doc/libs/1_57_0/boost/serialization/access.hpp,解决示例的编译错误,删除“#include #include " 并且有效!
  • 删除其他包含没有意义。它不能改变任何东西(显然序列化标头包含它)。关于不包括不受支持的存档类型的警告是另一回事,完全不相关(参见heredocs)。无论如何,只要看看我回答中的现场演示,看看它是否有效。
  • 是的,我明白你的意思。但奇怪的是,示例coliru.stacked-crooked.com/a/3215d33e3a81bf7d 无法在我的计算机上编译,除非我注释标题。我的编译命令是'g++ -std=c++11 main.cpp -lboost_serialization -I /usr/local/lib/libboost1.65.1/include/ -L /usr/local/lib/libboost1.65.1/lib/'。这些目录是从源代码编译的 boost 库。所以我猜我的编译环境有问题。
【解决方案2】:

我找出了这个错误的根本原因: 我使用的 gcc 和 g++ 版本太旧了:g++ 4.8.0。 Ubuntu 18.04 中的默认 gcc 和 g++ 版本是 7.5.0

我之所以使用g++ 4.8.0,是因为我想在我的Ubuntu中安装apollo自动驾驶工具包。 然后我也想在我的 Ubuntu 中尝试 LIO-SAM 映射工具包。 但是致命的错误出现了,LIO-SAM 以及 Boost、gtsam 和 ROS 等依赖项无法通过 g++ 4.8.0 编译。

所以要小心你的编译环境。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 2011-05-16
    • 2017-09-24
    • 2016-02-28
    • 1970-01-01
    • 2021-05-03
    相关资源
    最近更新 更多