c++ - 使用 mutable 允许修改 unordered_set 中的对象
问题描述
请考虑以下代码:
#include <iostream>
#include <unordered_set>
struct MyStruct
{
int x, y;
double mutable z;
MyStruct(int x, int y)
: x{ x }, y{ y }, z{ 0.0 }
{
}
};
struct MyStructHash
{
inline size_t operator()(MyStruct const &s) const
{
size_t ret = s.x;
ret *= 2654435761U;
return ret ^ s.y;
}
};
struct MyStructEqual
{
inline bool operator()(MyStruct const &s1, MyStruct const &s2) const
{
return s1.x == s2.x && s1.y == s2.y;
}
};
int main()
{
std::unordered_set<MyStruct, MyStructHash, MyStructEqual> set;
auto pair = set.emplace(100, 200);
if (pair.second)
pair.first->z = 300.0;
std::cout << set.begin()->z;
}
我正在使用mutable
允许修改z
. MyStruct
我想知道这是否可行且合法,因为该集合是 a) 无序 b) 我不z
用于散列或相等?
解决方案
我会说这是“可变”关键字的完美使用。
mutable 关键字用于标记不属于类“状态”的成员(即它们是某种形式的缓存或中间值,不代表对象的逻辑状态)。
您的相等运算符(以及其他比较器(或任何序列化数据的函数)(或生成哈希的函数))定义对象的状态。您的相等比较器在检查对象的逻辑状态时不使用成员“z”,因此成员“z”不是类状态的一部分,因此无法使用“可变”访问器。
现在这么说。我确实认为以这种方式编写代码非常脆弱。类中没有任何东西可以阻止未来的维护者不小心使 z 成为类状态的一部分(即将它添加到散列函数中),从而打破在std::unordered_set<>
. 因此,您应该非常明智地使用它,并花费大量时间编写注释和单元测试以确保维护前提条件。
我还将研究“@Andriy Tylychko”关于将类分解为 const 部分和 value 部分的评论,以便您可以将其用作std::unordered_map
.
推荐阅读
- windows - 找到超过 2 个 binskim 的 exe,恐慌!在 MobSF
- c - C、不带空格或制表符的字符串输入
- python - 字典和相似键的字典,只有字典理解
- android - 版本冲突(google-services 插件)
- javascript - 找到一个 html 元素
- apache-kafka - Kinesis 如何实现 Kafka 风格的 Consumer Groups?
- php - 如何从 MySQL 获取过去 7 天的行?
- aws-lambda - 无法导入模块“src/index”:Function.Module._load (module.js:438:3) 出错
- javascript - Get javascript values from calculation and insert them into mysql database
- php - Is it possible to treat $_POST like single quotes rather the double quotes?