使用 boost::dynamic_bitset 作为键值对序列化 boost::bimap

2023-12-07

我有兴趣序列化boost::bimap含有boost::dynamic_bitset这样我就可以保存它并在需要时加载回来。我已经尝试这样做,但遇到了很多错误。我随身携带的代码如下。

// Example program
#include <iostream>
#include <string>
#include <fstream>
#include <boost/bimap.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/unordered_multiset_of.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/vector.hpp>


namespace std {
    template <typename Block, typename Alloc>
    struct hash<boost::dynamic_bitset<Block, Alloc> > {

        using bitset_type = boost::dynamic_bitset<Block, Alloc>;
        using block_type = typename bitset_type::block_type ;

        size_t operator()(boost::dynamic_bitset<Block, Alloc> const& bs) const
        {
            thread_local static std::vector<block_type> block_data;
            auto blocks = bs.num_blocks();
            block_data.assign(blocks, 0);
            to_block_range(bs, block_data.begin());
            return boost::hash<std::vector<block_type>>()(block_data);
        }
    };
}


    namespace {
        template <typename Block>
        struct SerializableType {
            boost::dynamic_bitset<Block> x;
            private:
            friend class boost::serialization::access;
            template <class Archive> void serialize(Archive &ar, const unsigned int) {
                ar & BOOST_SERIALIZATION_NVP(x);
                }
                };
}

namespace bimaps = boost::bimaps;
    typedef boost::dynamic_bitset<> Bitset;
    typedef boost::bimap<
    bimaps::unordered_set_of<Bitset, std::hash<Bitset>>,
    bimaps::unordered_multiset_of<Bitset, std::hash<Bitset> > > bimap_reference;
    typedef bimap_reference::value_type position;
    bimap_reference index;

int main() {
    std::string val = "1010110110101010101";
    std::string key = "10010";

    boost::dynamic_bitset<> bits = boost::dynamic_bitset<> (val);
    boost::dynamic_bitset<> pos_bits = boost::dynamic_bitset<> (key);
    index.insert(position(pos_bits, bits));

    std::ofstream ofs("binaryfile");
    boost::archive::binary_oarchive oa(ofs);
    oa << BOOST_SERIALIZATION_NVP(index);    
    index::const_iterator iter = index.begin();    


    // first left elelemt of bimap
    boost::dynamic_bitset<> first_left = iter->left;
    const bimap_reference::left_iterator left_iter = index.left.find(first_left);
    oa << left_iter;

//  first right element of bimap
    auto pos = index.left.find(first_left);
    const bimap_reference::right_iterator right_iter = index.right.find(pos->second);
    oa << right_iter;
    std::cout <<"# done" << std::endl;
    ofs.close();


    std::cout <<"# Loading binary file ... " << std::endl;
    std::ifstream ifs("binaryfile"); // name of loading file
    boost::archive::binary_iarchive ia(ifs);
    ia >> index;
    bimap_reference::left_iterator left_iter;
    ia >> left_iter;
    bimap_reference::right_iterator right_iter;
    ia >> right_iter;
    std::cout<<"# done" << std::endl;
    ifs.close();
    return 0;
}

我该怎么做?。

EDIT_1:

显示编译器和链接器设置Eclispse(因为我在 @sehe 提供的答案代码中遇到了一些错误)。

enter image description here

enter image description here

enter image description here

EDIT_2

Linux终端上使用的命令g++ -std=c++14 -Os -Wall -pedantic -pthread main.cpp -lboost_serialization && ./a.out

Errors I get with the first answer code when tried in linux terminal and eclipse IDE.
/tmp/cc71hTC2.o: In function `boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>::vload(boost::archive::class_name_type&)':
main.cpp:(.text._ZN5boost7archive6detail15common_iarchiveINS0_15binary_iarchiveEE5vloadERNS0_15class_name_typeE[_ZN5boost7archive6detail15common_iarchiveINS0_15binary_iarchiveEE5vloadERNS0_15class_name_typeE]+0x1): undefined reference to `boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>::load_override(boost::archive::class_name_type&)'
/tmp/cc71hTC2.o: In function `void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost13serialization15throw_exceptionINS_7archive17archive_exceptionEEEvRKT_[_ZN5boost13serialization15throw_exceptionINS_7archive17archive_exceptionEEEvRKT_]+0x1a): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/cc71hTC2.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::exception_detail::error_info_injector<boost::archive::archive_exception> const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC2ERKS4_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS4_]+0x18): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/cc71hTC2.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::exception_detail::error_info_injector<boost::archive::archive_exception> const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC1ERKS4_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS4_]+0x19): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/cc71hTC2.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC2ERKS3_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS3_]+0xe): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/cc71hTC2.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC1ERKS3_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS3_]+0x14): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
collect2: error: ld returned 1 exit status

EDIT 3 Using g++ -std=c++14 -Os -Wall -pedantic -pthread main.cpp -lboost_serialization && ldd a.out我得到以下信息

/tmp/ccBH8KfT.o: In function `boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>::vload(boost::archive::class_name_type&)':
main.cpp:(.text._ZN5boost7archive6detail15common_iarchiveINS0_15binary_iarchiveEE5vloadERNS0_15class_name_typeE[_ZN5boost7archive6detail15common_iarchiveINS0_15binary_iarchiveEE5vloadERNS0_15class_name_typeE]+0x1): undefined reference to `boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>::load_override(boost::archive::class_name_type&)'
/tmp/ccBH8KfT.o: In function `void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost13serialization15throw_exceptionINS_7archive17archive_exceptionEEEvRKT_[_ZN5boost13serialization15throw_exceptionINS_7archive17archive_exceptionEEEvRKT_]+0x1a): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::exception_detail::error_info_injector<boost::archive::archive_exception> const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC2ERKS4_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS4_]+0x18): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::exception_detail::error_info_injector<boost::archive::archive_exception> const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC1ERKS4_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS4_]+0x19): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC2ERKS3_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS3_]+0xe): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'
/tmp/ccBH8KfT.o: In function `boost::exception_detail::error_info_injector<boost::archive::archive_exception>::error_info_injector(boost::archive::archive_exception const&)':
main.cpp:(.text._ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC1ERKS3_[_ZN5boost16exception_detail19error_info_injectorINS_7archive17archive_exceptionEEC5ERKS3_]+0x14): undefined reference to `boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)'

  1. 哇。您的目标并不是使用该哈希函数来提高性能。

    • 您正在复制每个键/值哈希上的所有块(例如,在查找时、在插入时)
    • you better永远不要使用协同例程,因为线程局部静态会让你的生活变得悲惨

    请参阅下面我的奖励部分

  2. 为什么这个尴尬的舞蹈(简化代码):

    auto iter = index.begin();
    
    // first left element of bimap
    BS first_left = iter->left;
    Index::left_iterator left_iter = index.left.find(first_left);
    

    出什么问题了

    auto left_iter = index.left.begin();
    
  3. 您认为序列化后迭代器的有效性如何? (看迭代器失效规则)

    oa << left_iter;
    

    我认为从存储中加载新的数据结构算作“重新分配”。迭代器或对另一个数据结构的引用在这里显然没有意义。

  4. 嗯。现在真的是越来越混乱了。

    //  first right element of bimap
    auto pos = index.left.find(first_left);
    Index::right_iterator right_iter = index.right.find(pos->second);
    

    您将其称为“第一个右侧元素”,但您执行了其他操作:找到与first_left键(很可能是右侧的最后一个元素。另请注意,由于 bimap 的右侧是multiset_of,可能有多个匹配项,您随机使用第一个。

    (边注:pos是无用的重复left_iter的值)

  5. See 3.

    oa << right_iter;
    
  6. Varia:

    • 确保以二进制方式打开文件

      std::ofstream ofs("binaryfile", std::ios::binary);
      std::ifstream ifs("binaryfile", std::ios::binary);
      
    • 为什么用值语义来命名容器index_reference?这只是不必要的混乱

    • SerializableType未使用
    • BOOST_SERIALIZATION_NVP对于二进制档案毫无意义(节点中没有名称)

真正的问题

我想,真正的问题可能是“我如何序列化Bitsets?”。我很高兴地告诉你,我在 2015 年写了所需的部分:如何序列化 boost::dynamic_bitset?并且拉取请求已被 Boost 接受从 1.64 版本开始.

因此,您可以坐下来,喝茶并包括:

#include <boost/dynamic_bitset/serialization.hpp>

All done.

奖金部分

既然该序列化实现了最小副本序列化,为什么不使用它来支持哈希函数呢?序列化机制将为您提供所需的私有访问。

我滥用序列化管道hash<>之前的专业:散列任意精度值 (boost::multi precision::cpp_int)

把它们放在一起

Live On Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/unordered_multiset_of.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/dynamic_bitset/serialization.hpp>
#include <fstream>
#include <iostream>
#include <string>

#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/stream.hpp>

#include <boost/functional/hash.hpp>

namespace serial_hashing { // see https://stackoverflow.com/questions/30097385/hash-an-arbitrary-precision-value-boostmultiprecisioncpp-int
    namespace io = boost::iostreams;

    struct hash_sink {
        hash_sink(size_t& seed_ref) : _ptr(&seed_ref) {}

        typedef char         char_type;
        typedef io::sink_tag category;

        std::streamsize write(const char* s, std::streamsize n) {
            boost::hash_combine(*_ptr, boost::hash_range(s, s+n));
            return n;
        }
      private:
        size_t* _ptr;
    };

    template <typename T> struct hash_impl {
        size_t operator()(T const& v) const {
            using namespace boost;
            size_t seed = 0;
            {
                iostreams::stream<hash_sink> os(seed);
                archive::binary_oarchive oa(os, archive::no_header | archive::no_codecvt);
                oa << v;
            }
            return seed;
        }
    };
}

namespace std {
    template <typename Block, typename Alloc> struct hash<boost::dynamic_bitset<Block, Alloc> >
        : serial_hashing::hash_impl<boost::dynamic_bitset<Block, Alloc> > 
    {};
} // namespace std

namespace bimaps = boost::bimaps;
using Bitset = boost::dynamic_bitset<>;

typedef boost::bimap<
    bimaps::unordered_set_of<Bitset, std::hash<Bitset> >,
     bimaps::unordered_multiset_of<Bitset, std::hash<Bitset> > > Index;

int main() {
    using namespace std::string_literals;

    {
        std::cout << "# Writing binary file ... " << std::endl;
        Index index;
        index.insert({Bitset("10010"s), Bitset("1010110110101010101"s)});

        std::ofstream ofs("binaryfile", std::ios::binary);
        boost::archive::binary_oarchive oa(ofs);
        oa << index;
    }

    {
        std::cout << "# Loading binary file ... " << std::endl;
        std::ifstream ifs("binaryfile", std::ios::binary); // name of loading file

        boost::archive::binary_iarchive ia(ifs);

        Index index;
        ia >> index;
    }
}

Prints

# Writing binary file ... 
# Loading binary file ... 

没问题。

后脚本

真的,省点麻烦吧。由于您的使用方式明确表明您不想要无序的语义,只需使其有序:

Live On Coliru

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/dynamic_bitset/serialization.hpp>
#include <fstream>
#include <iostream>

namespace bimaps = boost::bimaps;
using Bitset = boost::dynamic_bitset<>;

typedef boost::bimap<bimaps::set_of<Bitset>, bimaps::multiset_of<Bitset>> Index;

int main() {
    using namespace std::string_literals;

    {
        std::cout << "# Writing binary file ... " << std::endl;
        Index index;
        index.insert({Bitset("10010"s), Bitset("1010110110101010101"s)});

        std::ofstream ofs("binaryfile", std::ios::binary);
        boost::archive::binary_oarchive oa(ofs);
        oa << index;
    }

    {
        std::cout << "# Loading binary file ... " << std::endl;
        std::ifstream ifs("binaryfile", std::ios::binary); // name of loading file

        boost::archive::binary_iarchive ia(ifs);

        Index index;
        ia >> index;
    }
}

减少到 36 行,只剩下不到一半的代码。

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

使用 boost::dynamic_bitset 作为键值对序列化 boost::bimap 的相关文章

  • 如何动态加载包含非托管代码的原始程序集?(绕过“无法验证的代码失败策略检查”异常)

    我将举一个使用的例子系统 Data SQLite DLL http sqlite phxsoftware com 这是一个包含非托管代码的混合程序集 如果我执行这个 var assembly Assembly LoadFrom System
  • 如何使用 ILoggerFactory 记录 Polly 的重试

    或者 如何从静态方法记录 From https github com App vNext Polly https github com App vNext Polly你有这样的例子 其中记录器神奇地可用 Policy Timeout 30
  • WP8.1 C# 绑定联系人图像

    信息很简单 我正在尝试创建一个可以显示用户联系人的应用程序 我也是一名自学成才的程序员 所以我在某些方面有编程经验 但总体来说我对数据绑定相对较新 首先 我有一个 ListView 控件 其中包含图像绑定
  • 在调用堆栈中看到大量 clr!CLR Semaphore::Wait

    我们看到很多像下面这样的调用堆栈 我可以知道什么条件 情况会发生这种情况吗 OS Thread Id 0x48654 559 Current frame ntdll NtWaitForSingleObject 0xa Child SP Re
  • 使用预编译头减少 clang 编译时间

    我正在开发一个数据库项目 该项目将查询 以某种高级语言表示 编译为 C 代码 这段代码由数据库编译并执行 那部分工作得很好 现在 我正在尝试减少 C 查询代码的编译时间 我想知道是否可以使用预编译头来提高性能 该查询被转换为一个名为 Que
  • 在 DataGridView 中隐藏行非常慢

    我在 Winforms 应用程序中有一个 DataGridView 大约有 1000 行 未绑定 和 50 列 隐藏一列需要整整 2 秒 当我想隐藏大约一半的行时 这就成为一个问题 private void ShowRows string
  • Confuser .NET 混淆器。安全吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我目前正在开发一个应用程序 其中阻止用户反编译代码非常重要 现在 我意识到 如果由经验丰富的程序员执行 大多数 exe 都是可反编译的
  • WinForms - 表单大小错误

    我们有以下代码 private void MainForm Shown object sender EventArgs e RepositionForm private void RepositionForm Rectangle rect
  • Qt QML 数据模型似乎不适用于 C++

    我一直在使用中的示例http doc qt digia com 4 7 qdeclarativemodels html http doc qt digia com 4 7 qdeclarativemodels html这是 QML 声明性数
  • C for 循环索引:新 CPU 中的前向索引更快吗?

    在我订阅的邮件列表上 两位知识渊博的 IMO 程序员正在讨论一些优化的代码 并说了以下内容 在 5 8 年前发布的 CPU 上 向后迭代 for 循环稍微快一些 e g for int i x 1 i gt 0 i 因为比较i归零比将其与其
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 按值返回的函数的返回语句中的初始化

    我的问题源于深入研究std move in return语句 例如以下示例 struct A A std cout lt lt Constructed lt lt this lt lt std endl A A noexcept std c
  • printf() 使用字符串表“解码器环”调试库

    我写这封信是想看看你们中是否有人见过或听说过我即将描述的想法的实现 我有兴趣为嵌入式目标开发 printf 风格的调试库 目标非常遥远 并且我和目标之间的通信带宽预算非常紧张 因此我希望能够以非常有效的格式获取调试消息 通常 调试语句如下所
  • 只读有运行时开销吗?

    出于某种原因 我一直认为readonly字段有与其相关的开销 我认为这是 CLR 跟踪是否存在readonly字段是否已初始化 这里的开销是一些额外的内存使用量 用于跟踪状态以及分配值时的检查 也许我这么认为是因为我不知道readonly字
  • 该组件没有由 uri 标识的资源

    我想创建一个通用数据网格以在我的所有视图 用户控件上使用 这是我的结构 Class Library called Core Class called ViewBase public class ViewBase UserControl pu
  • EWS - 给予预约,获取预约的所有者副本

    在 EWS 中进行预约后 是否可以获得所有者的副本 例如 如果我登录为user1 我有user1创建的约会的副本user2 我有冒充权 我要编辑user2预约的副本 我怎样才能获得user2 s copy 您可以使用 PidLidClean
  • char* argv[] 在 c/c++ 中如何工作? [复制]

    这个问题在这里已经有答案了 我知道它用于使用命令行中的参数 但我没有得到声明 字符 argv 它是否意味着指向 char 数组的指针 如果是的话为什么没有大小 如果不是动态数组 就不需要有大小吗 我做了一些研究 发现有人说它会衰减为 cha
  • 如何使用 xamarin 表单提示用户进行地理定位

    我正在 Xamarin Forms 应用程序中开发一个应用程序 需要请求地理位置权限 如果获得许可 它需要从设备获取地理位置数据 然后将地理位置坐标放入 Forecast io URL 我正在使用 James 的 Geolocator 插件
  • 在 C# WinForms 中预览文档(Word、Excel、PDF、文本文件等)?

    我正在开发一个 C WinForms 应用程序 我希望能够 预览 其中的各种文档类型 也就是说 当用户从列表中选择文件名时 它会在下面以相同的形式显示所选文件的预览 这很像 Outlook 允许您无需双击即可预览选定邮件的方式 有没有什么方
  • 如何在 Winform DataGridView 中创建不同的单元格格式

    我有一个 DataGridView 我将其绑定到 DataTable DataTable 是一个全数字值 要求 DataGridView 中的每 n 行都包含文本 而不是数值 以便在视觉上为用户分隔部分 我很高兴在绑定后将此文本数据放入 D

随机推荐