【问题标题】:How to serialize a map of pointers in boost library?如何序列化boost库中的指针映射?
【发布时间】:2021-12-26 20:46:34
【问题描述】:

我想序列化一个指针映射

地图创建

float *data = new float[1000];
std::map<int, std::map<std::string, float*> > mapa;
mapa[4]["foo"] = data;

将映射序列化到文件

std::ofstream ofs("somefile");
boost::archive::binary_oarchive oa(ofs);
oa<<mapa;
ofs.close();

从文件加载地图:

std::ifstream ifs("somefile", std::ios::binary);
boost::archive::binary_iarchive ia(ifs);
std::map<int, std::map<std::string, float*> > newMapa;
ia >> newMapa;
ifs.close();

我怎样才能正确地做到这一点?

编译错误示例: https://godbolt.org/z/76fMbxMhf

【问题讨论】:

  • 你希望指针如何被序列化?它应该只是序列化指针中保存的地址,反序列化时不指向任何内容吗?没有关于可通过地图访问的指向数组大小的信息。
  • 我们可以假设指向数组的大小总是1000。
  • boost 库中是否有任何部分可以处理这些结构的序列化?我可以改写我的问题。
  • 对不起,我不能确定。如果指针不能被具有所有权语义的某种类型替换(std::array/std::vector),我只需将float* 包装在一个可以提供正确serialize 成员的类中。
  • 就我而言,我有十几个结构:指针映射。每个指针由cudaAlloc初始化,我想避免额外的覆盖。

标签: c++ boost


【解决方案1】:

强 typedef 旨在将原语包装成可跟踪的​​类型:https://www.boost.org/doc/libs/1_78_0/libs/serialization/doc/strong_typedef.html

BOOST_STRONG_TYPEDEF(float, Float)

但是,这将引入相当大的 (!) 开销,因为每个元素都需要跟踪。在您的示例中,将指针替换为数组索引会使 1000 倍更有意义。

当您使用它时,将其替换为 std::vector&lt;float&gt;,这样您就不会遇到终身问题(和泄漏)。

最后,在关闭文件甚至再次读取文件之前,请确保存档已完成。

参加 #1

Live On Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>

#include <fstream>
#include <iostream>
#include <numeric>
#include <sstream>

using ConvolutedIndex = std::map<int, std::map<std::string, size_t>>;

int main()
{   
    auto data = std::vector<float>(1000);
    std::iota(data.begin(), data.end(), 0.0); // fill with sample data

    float* element = &data[rand() % data.size()]; // pick random element

    std::cout << "Random pick: " << *element << " at " << element << "\n";

    {
        std::ofstream                   ofs("filename", std::ios::binary);
        boost::archive::binary_oarchive oa(ofs);
        oa << ConvolutedIndex{
            {4,
             {
                 {"foo", element - data.data()},
             }},
        };
    } // also closes file, but more importantly, completes archive first

    {
        std::ifstream                   ifs("filename", std::ios::binary);
        boost::archive::binary_iarchive ia(ifs);

        ConvolutedIndex newMapa;
        ia >> newMapa;

        std::cout<< "The element recovered: " << data.at(newMapa.at(4).at("foo")) << "\n";
    }
}

打印例如

Random pick: 383 at 0x1f142dc
The element recovered: 383

参加 #2

这仍然有问题,因为您从未序列化被索引的浮点数。容易补救:

Live On Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>

#include <fstream>
#include <iostream>
#include <numeric>
#include <sstream>

using Data            = std::vector<float>;
using ConvolutedIndex = std::map<int, std::map<std::string, size_t>>;

int main()
{   
    {
        Data data(1000);
        std::iota(data.begin(), data.end(), 0.0); // fill with sample data

        float* element = &data[rand() % data.size()]; // pick random element
        std::cout << "Random pick: " << *element << " at " << element << "\n";

        std::ofstream                   ofs("filename", std::ios::binary);
        boost::archive::binary_oarchive oa(ofs);

        oa << data << ConvolutedIndex{
            {4,
             {
                 {"foo", element - data.data()},
             }},
        };
    } // also closes file, but more importantly, completes archive first

    {
        std::ifstream                   ifs("filename", std::ios::binary);
        boost::archive::binary_iarchive ia(ifs);

        Data            newData;
        ConvolutedIndex newMapa;
        ia >> newData >> newMapa;

        std::cout<< "The element recovered: " << newMapa.at(4).at("foo") << "\n";
    }
}

现在每个人都很高兴(好吧,除了Gods of &lt;random&gt;,但读者需要做一些练习):

Random pick: 383 at 0x1bd930c
The element recovered: 383

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 2014-07-01
    • 2016-04-21
    • 2016-09-06
    • 1970-01-01
    相关资源
    最近更新 更多