gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:29 25 4
gpt4 key购买 nike

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

// 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

编辑 3 使用 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. 哇。您的目标不是该哈希函数的性能。

    • 您正在复制每个键/值散列上的所有 block (例如,在查找时、在插入时)
    • 最好永远不想使用协程,因为线程局部静态会让你的生活变得悲惨

    请参阅下面我的奖励部分

  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. 您认为序列化时迭代器的有效性是什么? (参见 Iterator invalidation rules)

    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 的迭代器键(很可能是右侧的最后一个元素。另请注意,由于双图的右侧是 multiset_of ,因此可能有多个匹配项,您随机使用第一个。

    (旁注:posleft_iter 值的无用重复)

  5. 见 3.

    oa << right_iter;
  6. 变种:

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

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

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

真正的问题

我想,真正的问题可能是“我如何序列化 Bitset s?”。我很高兴地通知您我在 2015 年编写了所需的位:How to serialize boost::dynamic_bitset?并且拉取请求已被 Boost 接受 starting with version 1.64 .

所以,您可以坐下来喝茶,包括:

#include <boost/dynamic_bitset/serialization.hpp>

全部完成

奖金部分

既然序列化实现了最小拷贝序列化,为什么不用它来驱动哈希函数呢?序列化机制将为您提供所需的私有(private)访问权限。

我滥用了 hash<> 的序列化管道之前的特化:Hash an arbitrary precision value (boost::multiprecision::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;
}
}

打印

# 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 行,剩下的代码还不到一半。

关于c++ - 使用 boost::dynamic_bitset 作为键值对序列化 boost::bimap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47530399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com