【发布时间】:2016-07-31 17:14:59
【问题描述】:
我正在编写一个自定义的OrderedTree 类,我想将其用作unordered_set 的键。
在对树进行哈希处理时,我想做几件事:
- 懒惰地计算哈希并根据需要缓存(因为这可能是一项昂贵的操作),
- 也许平衡树。
这些操作都不会改变对象的语义相等或哈希值,但它们确实会修改一些私有字段。
不幸的是,尝试在 std::hash<Tree>::operator() 内部修改 OrderedTree 中的任何成员似乎违反了 unordered_set 所期望的 const 正确性。
我可以将OrderedTree 与unordered_set 一起使用吗?如果有,怎么做?
编辑:
根据 cmets 中的要求,最低限度的概念证明:
#include <unordered_set>
std::size_t hash_combine(std::size_t a, std::size_t b) {
// TODO: Copy from boost source or something
return 0;
}
struct Node {
int value;
Node *left, *right, *parent;
std::size_t hash(std::size_t seed) const {
if (left != nullptr)
seed = left->hash(seed);
std::hash<int> hasher;
seed = hash_combine(seed, hasher(value));
if (right != nullptr)
seed = right->hash(seed);
return seed;
}
};
struct Tree {
Tree(): hash_(0), root(nullptr) {}
Node *root;
std::size_t hash() const {
if (hash_ == 0 && root != nullptr) {
hash_ = root->hash(7);
}
return hash_;
}
private:
std::size_t hash_;
};
namespace std {
template<>
struct hash<Tree> {
std::size_t operator()(const Tree& t) const {
return t.hash();
}
};
}
int main() {
std::unordered_set<Tree> set;
}
当我尝试编译时,我得到:
Sample.cc:31:13: error: cannot assign to non-static data member within const member function 'hash'
hash_ = root->hash(7);
~~~~~ ^
Sample.cc:29:15: note: member function 'Tree::hash' is declared const here
std::size_t hash() const {
~~~~~~~~~~~~^~~~~~~~~~~~
【问题讨论】:
-
“似乎违反了 const 正确性”是如何表现出来的?这只是一些普遍的焦虑,还是您不知道如何实现它,或者您是否遇到编译器错误?
-
听说过关键字“可变”吗?
-
@JVApen 我以前没有。谢谢!这似乎正是我正在寻找的。如果您发布答案,我会接受。
-
标签: c++ c++11 hash constants unordered-set