在boost中对bucket使用vector
Using vector for buckets in boost intrusive
如何用std::vector
管理boost::intrusive::unordered_set
的bucket?以下代码让我做噩梦:
#include <boost/intrusive/unordered_set.hpp>
#include <vector>
#include <cstdint>
namespace BI = boost::intrusive;
struct ValuableData : public BI::unordered_set_base_hook<>
{
int x;
int y;
char c;
};
typedef BI::base_hook<BI::unordered_set_base_hook<>> Options;
typedef BI::unordered_bucket<Options>::type BucketType;
typedef BI::unordered_bucket_ptr<Options>::type BucketPtr;
struct VectorTraits{
std::vector<BucketType> v;
BucketPtr bucket_begin(){
return v.data();
}
uint32_t bucket_count() const {
return v.capacity();
}
};
struct dumhash{
uint32_t operator()(const ValuableData &data) const {
return data.x;
}
};
struct dumcomp{
bool operator()(const ValuableData &data, const ValuableData &datb) const {
return true;
}
};
typedef BI::unordered_set<ValuableData,
BI::hash<dumhash>,
BI::equal<dumcomp>,
BI::bucket_traits<VectorTraits>> MySet;
int main(){
VectorTraits tr;
tr.v.reserve(100);
tr.v.push_back(BucketType()); //.data() may return null is vector is empty.
MySet set(tr);
set.rehash(tr);
return 0;
}
错误消息指示违反了const
限定符。我的boost
版本是1.73.0,我的编译器g++10.2.0。我必须使用c++17
。
boost侵入式手册提到了const_bucket_ptr
,但没有说明如何达到该类型。我怀疑这是我的错误的来源,请参阅:https://www.boost.org/doc/libs/1_74_0/doc/html/intrusive/unordered_set_unordered_multiset.html#intrusive.unordered_set_unordered_multiset.custom_bucket_traits
编辑:我用一个可以在家里完全编译的更简单的例子替换了以前实际使用的代码。这是我的完整错误信息:
In file included from include/boost/intrusive/unordered_set.hpp:18,
from src/BoostIntrusiveSet.cpp:9:
include/boost/intrusive/hashtable.hpp: In instantiation of 'void boost::intrusive::hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::rehash_impl(const bucket_traits&, bool) [with ValueTraits = boost::intrusive::bhtraits<ValuableData, boost::intrusive::slist_node_traits<void*>, boost::intrusive::safe_link, boost::intrusive::dft_tag, 4>; VoidOrKeyOfValue = void; VoidOrKeyHash = dumhash; VoidOrKeyEqual = dumcomp; BucketTraits = VectorTraits; SizeType = long long unsigned int; long long unsigned int BoolFlags = 3; boost::intrusive::hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::bucket_traits = VectorTraits]':
include/boost/intrusive/hashtable.hpp:2944:13: required from 'void boost::intrusive::hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::rehash(const bucket_traits&) [with ValueTraits = boost::intrusive::bhtraits<ValuableData, boost::intrusive::slist_node_traits<void*>, boost::intrusive::safe_link, boost::intrusive::dft_tag, 4>; VoidOrKeyOfValue = void; VoidOrKeyHash = dumhash; VoidOrKeyEqual = dumcomp; BucketTraits = VectorTraits; SizeType = long long unsigned int; long long unsigned int BoolFlags = 3; boost::intrusive::hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::bucket_traits = VectorTraits]'
src/BoostIntrusiveSet.cpp:64:15: required from here
include/boost/intrusive/hashtable.hpp:3153:73: error: passing 'const bucket_traits' {aka 'const VectorTraits'} as 'this' argument discards qualifiers [-fpermissive]
3153 | const bucket_ptr new_buckets = new_bucket_traits.bucket_begin();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
compilation terminated due to -Wfatal-errors.
文档指出需要bucket_begin()
的常量重载:
用户定义的bucket特性必须满足以下接口:
class my_bucket_traits { bucket_ptr bucket_begin(); const_bucket_ptr bucket_begin() const; std::size_t bucket_count() const; };
我不知道你为什么认为你可以安全地让桶特征拥有一个桶容器。该示例的作用是将指针存储到bucket。这解决了以下问题:
- bucket特性可廉价复制
- bucket的生存期不与特性的副本绑定(因为不持有所有权(
- bucket数据自然不是常量,即使trait实例是
固定
在这里应用相同的方法:
在Coliru上直播
#include <boost/intrusive/unordered_set.hpp>
#include <vector>
#include <iostream>
namespace BI = boost::intrusive;
struct ValuableData : public BI::unordered_set_base_hook<> {
int x = 0;
int y = 0;
char c = 0;
};
using Options = BI::base_hook<BI::unordered_set_base_hook<> >;
using BucketType = BI::unordered_bucket<Options>::type;
using BucketPtr = BI::unordered_bucket_ptr<Options>::type;
struct VectorTraits {
std::vector<BucketType>* v;
BucketPtr bucket_begin() const { return v->data(); }
[[nodiscard]] uint32_t bucket_count() const { return v->capacity(); }
};
struct dumhash {
uint32_t operator()(const ValuableData& data) const { return data.x; }
};
struct dumcomp {
bool operator()(const ValuableData& data, const ValuableData& datb) const {
return data.x == datb.x;
}
};
typedef BI::unordered_set<ValuableData, BI::hash<dumhash>, BI::equal<dumcomp>,
BI::bucket_traits<VectorTraits>>
MySet;
int main() {
std::vector<BucketType> buckets(13);
VectorTraits tr { &buckets };
MySet set(tr);
set.rehash(tr);
std::cout << buckets.size() << "n";
buckets.resize(57);
set.rehash(tr);
std::cout << buckets.size() << "n";
}
打印
13
57
相关文章:
- 在某些循环内使用vector.push_back时出现分段错误
- execvp() 使用 vector<string *>
- 在 C++ 中使用 Vector 在动态数组中插入值,循环
- 如何使用vector.begin()和vector.end()遍历矩阵?
- 在不使用vector.end()的情况下迭代std::vector
- 使用 vector 检查表达式中的括号是否平衡
- 使用 vector.sort() 的非静态成员函数无效使用
- 如何在不使用 vector::erase() 的情况下编写自定义 Vector 方法来删除元素?
- 使用 vector<thread> 和 .join() 未并行运行的多线程C++程序
- 如何在用户定义类型的向量上使用 vector::p ush_back() 来仅修改一个对象?
- 在 C++ 中使用 vector 传递任意数量的参数
- 我们可以在 c++ 中使用 vector 来获取未知大小的用户输入,直到我们按回车键
- 如何使用<vector>构造函数
- 如果我不使用 vector.reserve(),为什么我的指针会失效?
- 使用 vector 在 c++ 中声明 3D 数组结构
- 使用 vector push_back类对象
- 如果我们可以使用 vector[1] = someInt,emplace() 的目的是什么
- 使用vector最小化堆分配会导致seg错误
- 为什么在这种情况下使用 vector<>.push_back() 时不使用动态内存?
- C++,使用 vector<int[2]> 我可以push_back({someNum1,someNum2})吗?