假设我们有一个简单的结构,如下面的
struct T{
int x;
int y;
};
T t1, t2;
还假设我有一个map<T, int> myMap
,并且仅使用T
值比较两个x
类型的结构。即t1 < t2
iff t1.x < t2.x
。我试图通过myMap更新键的一些y
值。这不应该影响地图看到键的方式。除了删除旧元素和插入新元素之外还有其他方法吗?
答案 0 :(得分:13)
如果您确定y
没有参与您班级的“逻辑状态”并且仅仅是一个实施细节,那么您可以声明它mutable
:
struct T
{
int x;
mutable int y;
bool operator<(const T& rhs) const { return x < rhs.x; }
};
现在你应该能够改变y
:
for (auto it = m.begin(); it != m.end(); ++it)
{
it->first.y = -2; // ouch? But it won't invalidate the map's invariants.
}
答案 1 :(得分:9)
不,map
不能让你修改密钥,因为这会使地图不变量无效(元素的排序) - 你知道它不会,但是map
不能知道,所以它在谨慎方面犯了错误并且不允许这样做。
删除并重新插入是一种正确的方法。将密钥视为不可变。
答案 2 :(得分:4)
如果y
没有参与比较,您可以将其标记为mutable
,因此即使值不变也可以修改。
答案 3 :(得分:1)
std::map
的键是const。所以你无法改变它。
此外,如果您仅使用x
来比较密钥,那么为什么要std::map<T,int>
?为什么不:
std::map<int, std::pair<T,int> > data; //where keys would be t.x
毕竟,在您的地图中,密钥实际上是t.x
。
答案 4 :(得分:1)
如果T::y
不影响比较操作员行为,则可以修改它。另一方面,修改map键的样式很糟糕,它应该是不可变的。标准库的某些实现允许修改密钥。
答案 5 :(得分:0)
键在地图中是常量,尝试将新值复制到新地图中。
答案 6 :(得分:0)
就像Cat说的那样,你不应该出于很多好理由改变密钥,但你似乎已经知道了足够的进展。
用const_cast抛弃键的常量,你不能做各种各样的伤害......错误的改变。只需仔细检查比较运算符在修改后仍然返回相同的内容。