如何为自定义类正确配置并使用boost::unordered_set
问题根源及修复方案
代码存在4个核心错误,逐一修复即可:
- 哈希函数适配错误:
boost::unordered_set<myclass>会通过ADL查找接收myclass类型参数的hash_value函数,你当前写的静态成员函数参数是vector<E>,完全不匹配,自然不会被调用。 operator==定义错误:你当前的运算符参数是vector<E>,且多写了一个冗余的>,同时未加const修饰,不符合unordered_set要求的相等比较规则(需要支持两个myclass常量对象的比较)。- 哈希函数内部变量未定义:你写的
d.name、d.scope中的d没有任何声明,实际需要遍历传入的E元素集合逐个计算哈希。 - 哈希函数可见性问题:如果不自定义哈希结构体传入unordered_set,需要将
hash_value放到boost命名空间下,才能被unordered_set正常查找调用。
修复后的完整代码示例
首先修正myclass类定义:
struct E { // 此处为E的示例结构,可根据你的实际定义调整 std::string name; int scope; }; class myclass { private: std::vector<E> lhs; public: myclass(const std::vector<E>& v) : lhs(v) {}; // 给哈希函数开放私有成员访问权限 friend size_t hash_value(const myclass& obj); // 修正相等比较运算符的参数、const修饰 bool operator==(const myclass& rhs) const { if (lhs.size() != rhs.lhs.size()) return false; for (size_t i = 0; i < lhs.size(); i++) { if (lhs[i].name != rhs.lhs[i].name || lhs[i].scope != rhs.lhs[i].scope) { return false; } } return true; } }; // 放在boost命名空间下让unordered_set可查找,参数为myclass类型 namespace boost { size_t hash_value(const myclass& obj) { size_t seed = 0; // 遍历所有E元素累加哈希值 for (const auto& e : obj.lhs) { boost::hash_combine(seed, e.name); boost::hash_combine(seed, e.scope); } return seed; } }
test函数无需修改即可正常运行:
void test(std::vector<std::vector<E>>& A) { boost::unordered_set<myclass> input_records(A.size()); for (auto it = A.begin(); it != A.end(); ++it) { auto k = input_records.insert(myclass{*it}); // 剩余业务逻辑 } }
可选实现:显式传入自定义哈希结构体
如果你不想将哈希函数放到boost命名空间,也可以自定义哈希结构体直接传给unordered_set:
struct MyClassHash { size_t operator()(const myclass& obj) const { // 哈希计算逻辑和上述hash_value实现一致即可 } }; // 声明unordered_set时显式指定哈希器 boost::unordered_set<myclass, MyClassHash> input_records(A.size());
内容的提问来源于stack exchange,提问作者yendang9423082
相关产品推荐
相关产品推荐

