簡體   English   中英

如何在boost庫中序列化指針的map?

[英]How to serialize a map of pointers in boost library?

我想序列化一個map 的指針

Map 創建

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

將 map 序列化到文件

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

從文件加載 map:

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

強 typedef 旨在將原語包裝成可跟蹤的類型: https://www.boost.org/doc/libs/1_78_0/libs/serialization/doc/strong_typedef.html

BOOST_STRONG_TYPEDEF(float, Float)

然而,這將引入相當大的 (,) 開銷。 因為在您的示例中,每個元素都需要跟蹤。 用數組索引替換指針會使 1000 倍更有意義。

當您使用它時,請將其替換為std::vector<float>這樣您就不會遇到生命周期問題(和泄漏)。

最后,在關閉文件甚至再次讀取文件之前,請確保存檔已完成。

拿#1

住在科利魯

#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

這仍然有問題,因為您從未序列化被索引的浮點數。 輕松補救:

住在科利魯

#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";
    }
}

現在每個人都很高興(好吧,除了<random>的神,但需要為讀者做一些練習):

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM