std::unordered_set透明哈希下,如何安全修改元素非键成员?
问题:在std::unordered_set中修改元素的非key字段的优雅方案?
我定义了如下类型S,希望将其实例存储在std::unordered_set中:
struct S { int key; // key在概念上属于S,且S需要访问它。 int data; bool operator==(S const& rhs) const { return key == rhs.key; } bool operator==(int key) const { return this->key == key; } };
搭配对应的哈希器:
struct SHash { using is_transparent = void; // 假设std::hash<int>为恒等函数。 size_t operator()(S const& s) const { return s.key; } size_t operator()(int key) const { return key; } };
此时可以通过key在哈希表中查找元素:
int main() { std::unordered_set<S, SHash, std::equal_to<>> s; s.insert(S{ .key = 0, .data = 1 }); s.insert(S{ .key = 1, .data = 2 }); assert(s.find(0)->data == 1); }
但无法修改哈希表中的元素非key字段:
s.find(0)->data = 3; // 无法编译
这是合理的:修改key会破坏哈希表结构,而find返回的迭代器无法知晓实际的key或哈希器的哈希逻辑。
若需修改S对象的非key部分,现有两种方案都不够优雅:
- 使用
std::unordered_map(内部本质是存储std::pair的unordered_set),但需要存储两次key; - 用
const_cast移除find返回引用的常量性,寄希望于始终不修改key,但这种用法违反标准库约定,虽能编译运行但风险极高。
是否存在其他更优雅的解决方案?
注:示例中重载operator==的方式并非最佳实践,仅为简化示例。
内容的提问来源于stack exchange,提问作者chrysante
相关产品推荐
相关产品推荐

