[英]What is wrong with this map?
I am a bit puzzled, why the following code is not working as expected... 我有点困惑,为什么以下代码没有按预期工作...
#include <iostream>
#include <map>
struct Foo {
int x,y,z;
Foo(int x,int y,int z) : x(x),y(y),z(z) {}
bool operator<(const Foo& other) const {
if (x > other.x) return false;
if (y > other.y) return false;
if (z > other.z) return false;
return true;
}
bool operator==(const Foo& other) const {
if (other.x != x) return false;
if (other.y != y) return false;
if (other.z != z) return false;
return true;
}
};
int main() {
Foo f(1,2,3);
std::map<Foo,double> map;
map[f] = 1.0;
std::cout << map[f] << "\n";
}
It prints 0
and not 1
. 它打印
0
而不是1
。 What did I do wrong? 我做错了什么?
code also here: http://ideone.com/fork/HMwPQ7 代码也在这里: http : //ideone.com/fork/HMwPQ7
It is because your operator<
has been implemented incorrectly. 这是因为您的
operator<
已被错误地实施。 Here is the correct version: 这是正确的版本:
bool operator<(const Foo& other) const {
if (x != other.x) return x < other.x;
else if (y != other.y) return y < other.y;
return z < other.z;
}
That basically says if x
are equal, then compare y
, if that too equals, then compare z
. 这基本上说如果
x
相等,那么比较y
,如果它也等于,则比较z
。
Read about Strict Weak Ordering . 阅读严格的弱排序 。
A shorter implementation could be this: 较短的实现可能是这样的:
bool operator<(const Foo& other) const {
return std::tie(x, y,z) < std::tie(other.x, other.y, other.z);
}
Hope that helps. 希望有所帮助。
Foo::operator <
does not define the strict weak ordering required by std::map
. Foo::operator <
没有定义std::map
所需的严格弱排序 。
In particular, given two identical Foo
s a
and b
, both a < b
and b < a
are true, when they should both be false. 特别地,给定两个相同的
Foo
a
和b
, a < b
和b < a
都是真的,当它们都应该是假的时。
Since you broke std::map
's contract, the behaviour is undefined. 由于您违反了
std::map
的合同,因此行为未定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.