std unique_ptrs 的 stl 集合的 boost 序列化

2024-01-07

我希望能够序列化 std::unique_ptrs 的 stl 容器。能做到吗? 顺便说一句,单个 std::unique_ptr 一切正常。 下面是我正在处理的代码,gcc 给出以下错误:

 use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const
 std::unique_ptr<_Tp, _Dp>&) [with _Tp = MyDegrees; _Dp =
 std::default_delete<MyDegrees>; std::unique_ptr<_Tp, _Dp> =
 std::unique_ptr<MyDegrees>]’

我怎样才能使代码工作?

#include <iostream>
#include <memory>
#include <fstream>
#include <map>
#include <vector>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
namespace boost {
namespace serialization {

template<class Archive, class T>
inline void save(
    Archive & ar,
    const std::unique_ptr< T > &t,
    const unsigned int file_version
) {
    // only the raw pointer has to be saved
    const T * const tx = t.get();
    //ar << tx;
    ar << boost::serialization::make_nvp("px", tx);
}
template<class Archive, class T>
inline void load(
    Archive & ar,
    std::unique_ptr< T > &t,
    const unsigned int file_version
) {
    T *pTarget;
    //ar >> pTarget;
    ar >> boost::serialization::make_nvp("px", pTarget);

#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
    t.release();
    t = std::unique_ptr< T >(pTarget);
#else
    t.reset(pTarget);
#endif
}
template<class Archive, class T>
inline void serialize(
    Archive & ar,
    std::unique_ptr< T > &t,
    const unsigned int file_version
) {
    boost::serialization::split_free(ar, t, file_version);
}
} // namespace serialization
} // namespace boost

class MyDegrees
{
public:
    void setDeg(int d) {
        deg = d;
    }
    int getDeg()const {
        return deg;
    }
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    //{ ar & deg; }
    {
        ar & boost::serialization::make_nvp("DEGS", deg);
    }
    int deg;
};
class gps_position
{
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    //{ ar & degrees;  }
    {
        ar & boost::serialization::make_nvp("DEGS2", degrees);
        ar & boost::serialization::make_nvp("DEGMAP", deg_map);
    }
    std::unique_ptr<MyDegrees> degrees;
    std::vector<std::unique_ptr<MyDegrees> > deg_map;
public:
    gps_position(): degrees(std::unique_ptr<MyDegrees>(new MyDegrees)) {};
    void setDeg(int d) {
        degrees->setDeg(d);
    }
    int getDeg() const {
        return degrees->getDeg();
    }
};

int TestBasicSerialize(int, char *[])
{
    int numErr = 0;
    double a;
    std::ofstream ofs("filename");
    gps_position g;
    g.setDeg(45);
    std::cout<<g.getDeg()<<std::endl;
    {
        boost::archive::text_oarchive oa(ofs);
        oa << g;
    }
    //{ boost ::archive::xml_oarchive oa(ofs); oa << g;}
    gps_position newg;
    {
        std::ifstream ifs("filename");
        boost::archive::text_iarchive ia(ifs);
        ia >> newg;
        std::cout<<newg.getDeg()<<std::endl;
    }
    return numErr;

}

问题在于容器反序列化器正在尝试复制构造 unique_ptr。 为了进行演示,请考虑以下产生相同错误的代码:

std::vector< std::unique_ptr<int> > vec;
std::unique_ptr<int> p;
vec.push_back(p); // does not compile!

然而,这可以通过使用来解决std::move:

vec.push_back(std::move(p)); // ok

最省力的解决方案是使用可复制构造的智能指针, 例如boost::shared_ptr,其中带有 其预定义的序列化实现boost/serialization/shared_ptr.hpp.


下一个解决方案是在类中手动序列化向量:

//NOTE: this replaces void serialize(...) in gps_position
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
    ar & BOOST_SERIALIZATION_NVP(degrees);
    size_t size = deg_map.size();
    ar & BOOST_SERIALIZATION_NVP(size);
    for( auto it=deg_map.begin(), end=deg_map.end(); it!=end; ++it )
       ar & boost::serialization::make_nvp("item",*it);
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
    ar & BOOST_SERIALIZATION_NVP(degrees);
    size_t size = 0;
    ar & BOOST_SERIALIZATION_NVP(size);
    deg_map.clear();
    deg_map.reserve(size);
    while( size-- >= 0 ) {
        std::unique_ptr<MyDegrees> p;
        ar & boost::serialization::make_nvp("item",p);
        deg_map.push_back(std::move(p));
    }
}
BOOST_SERIALIZATION_SPLIT_MEMBER()

最后一个解决方案涉及编写您自己的容器序列化器, 就像您对 unique_ptr 所做的那样,它使用std::move添加项目:

namespace boost { namespace serialization {
//NOTE: do not include boost/serialization/vector.hpp
template<class Archive, class T, class Allocator>
inline void save(
    Archive & ar,
    const std::vector<T, Allocator> &t,
    const unsigned int
){
    collection_size_type count (t.size());
    ar << BOOST_SERIALIZATION_NVP(count);
    for(auto it=t.begin(), end=t.end(); it!=end; ++it)
        ar << boost::serialization::make_nvp("item", (*it));
}

template<class Archive, class T, class Allocator>
inline void load(
    Archive & ar,
    std::vector<T, Allocator> &t,
    const unsigned int
){
    collection_size_type count;
    ar >> BOOST_SERIALIZATION_NVP(count);
    t.clear();
    t.reserve(count);
    while( count-- > 0 ) {
        T i;
        ar >> boost::serialization::make_nvp("item", i);
        t.push_back(std::move(i)); // use std::move
    }
}

template<class Archive, class T, class Allocator>
inline void serialize(
    Archive & ar,
    std::vector<T, Allocator> & t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}
} } // namespace boost::serialization

最后但并非最不重要的一点是,您应该使用:

oa << BOOST_SERIALIZATION_NVP(g);
// and
ia >> BOOST_SERIALIZATION_NVP(newg);

使用 xml 存档时在 TestBasicSerialize() 中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std unique_ptrs 的 stl 集合的 boost 序列化 的相关文章

随机推荐

  • 如何将 CMake 输出放入“bin”目录?

    我目前正在构建一个具有插件结构的项目 我正在使用 CMake 来编译该项目 这些插件编译在单独的目录中 我的问题是 CMake 编译并将二进制文件和插件 动态库保存在源的目录结构中 如何让 CMake 将文件保存在类似 bin目录 正如奥列
  • 使用 Xoauth2 对 Gmail smtp 进行身份验证。结果用户名和密码不被接受

    由于最近删除了不太安全的应用程序 https support google com accounts answer 6010255 hl en并不想沿着一条路走下去应用程序密码 https support google com accoun
  • Windows操作系统中是否存在零拷贝?

    Reading 这篇零复制文章 http www ibm com developerworks library j zerocopy Windows 操作系统 服务器 2003 2008 2008 R2 中是否存在零拷贝 是的 它是通过以下
  • Angular:类型错误:无法读取 null 的属性“firstCreatePass”

    将 Angular 更新到版本 10 后 我看到此控制台错误 错误类型错误 无法读取 null 的属性 firstCreatePass 更新之前是不存在的 当使用自定义组件加载视图时会显示它 可能缺少什么 原来是因为我也更新了 ngx cu
  • 在 iPhone X 模拟器的顶部和底部看到黑条

    在 iPhone X 模拟器 GM Seed 中运行我的应用程序时 我注意到两个奇怪的效果 该应用程序不使用全屏空间 顶部和底部区域为黑色 标题栏下方有一个奇怪的白条 有谁知道这里发生了什么以及如何解决这个问题 我在 Interface B
  • 检查 T-SQL 中字符串的起始字符是否按字母顺序排列

    是否可以仅使用 TSQL 检查 varchar 字段的前两个字符是否按字母顺序排列 我需要选择my table只有具有的行my field以两个字母字符开头 我怎样才能实现这个目标 是否可以使用正则表达式 你不需要使用正则表达式 LIKE足
  • 为什么reactjs中的功能组件没有实例?

    In 反应快速入门 https facebook github io react docs refs and the dom html 有关于Refs and Functional Components that 您不能在功能组件上使用 r
  • HTTP 标头值的最大值?

    HTTP 标头是否有可接受的最大允许大小 如果是这样 那是什么 如果不是 这是特定于服务器的内容还是允许任何大小的标头的公认标准 不 HTTP 没有定义任何限制 然而 大多数网络服务器确实限制它们接受的标头的大小 例如在Apache 默认限
  • CSS/HTML:使文本斜体的正确方法是什么?

    是什么correct使文本斜体的方法 我见过以下四种方法 i Italic Text i em Italic Text em span class italic Italic Text span span class footnote It
  • (在Video.js中)如何设置自定义请求标头?

    遇到这个问题后 我根据以下内容编写了一个最小的示例本文档 https github com videojs http streaming hlsxhr
  • 向 Django 管理站点添加忘记密码功能

    如何将忘记密码功能添加到 Django 管理站点 有电子邮件 安全问题选项吗 有可用的插件 扩展吗 它们都是在 django 中构建的 只需添加相关的 url 模式即可 如下 from django contrib auth import
  • 使用 $ 运算符将两个括号链接在一起

    我有这个功能 min max 10 20 max 30 40 我可以将其重写为 min max 10 20 max 30 40 但是还有没有办法解决最后的括号呢 并不是说这还不够好 但我只是不能放弃这个想法 必须有某种方法可以做到这一点 如
  • 休眠序列不存在

    我尝试使用 spring 在我的项目中将 hibernate 从 4 升级到 54 2版本 升级后 当我调用更新方法时 我在堆栈跟踪中发现以下错误 10 53 32 185 ERROR TableStructure 149 could no
  • 在 WebView 中启用长按

    在浏览器中 您可以长按 URL 在我的 WebView 中 你不能 我怎样才能做到你也能做到 我也有同样的问题 不幸的是 我找不到一种方法来显示标准浏览器菜单选项 您必须自己实现每一项 我所做的是将 WebView 注册为上下文菜单acti
  • 通过 ingress 服务从 kubernetes pod 发送 http 请求到 Minikube 中的另一个 pod

    我在 Oracle VM Virtualbox 中使用 Minikube 单节点 Kubernetes 集群 节点中的一个 Pod 是基于 Next js 的客户端 其余 Pod 是不同的微服务 假设我的客户端 Pod1 需要在渲染之前向身
  • Firebase 数据库规则语法错误

    rules Users user id Grants write access to the owner of this user account whose uid must exactly match the key user id w
  • 如何自动生成创建或修改的时间戳字段?

    我的实体类 Entity Table name user public class User implements Serializable private static final long serialVersionUID 1L Id
  • Unity DI 从特定程序集自动注册

    我正在尝试使用 Unity Registration by Convention 功能 我不知道如何从特定的程序集 项目文件中注册以 Repository 结尾的文件 container RegisterTypes AllClasses F
  • 制作 python 程序发牌时遇到的麻烦。

    我想做一个纸牌游戏 我所坚持的是发牌 我所做的就是对每张卡制定一个指令 并赋予它一个值 因为有些卡比其他卡更有价值 我的想法是将字典分成4部分 或者将每本字典复印4份 然后从每份中删除39张卡片 每人留下13张卡片 这是否可能 或者我是否以
  • std unique_ptrs 的 stl 集合的 boost 序列化

    我希望能够序列化 std unique ptrs 的 stl 容器 能做到吗 顺便说一句 单个 std unique ptr 一切正常 下面是我正在处理的代码 gcc 给出以下错误 use of deleted function std u