这张地图有什么问题?
What is wrong with this map?
我有点纳闷,为什么下面的代码没有按预期运行...
#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";
}
它打印 0
而不是 1
。我做错了什么?
Foo::operator <
没有定义 std::map
所要求的 strict weak ordering。
特别是,给定两个相同的 Foo
s a
和 b
,a < b
和 b < a
都为真,而它们本应为假。
由于您违反了 std::map
的合同,因此行为未定义。
是因为你的operator<
实现不正确。这是正确的版本:
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;
}
基本上就是说,如果 x
相等,则比较 y
,如果太相等,则比较 z
。
一个较短的实现可能是这样的:
bool operator<(const Foo& other) const {
return std::tie(x, y,z) < std::tie(other.x, other.y, other.z);
}
希望对您有所帮助。
我有点纳闷,为什么下面的代码没有按预期运行...
#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";
}
它打印 0
而不是 1
。我做错了什么?
Foo::operator <
没有定义 std::map
所要求的 strict weak ordering。
特别是,给定两个相同的 Foo
s a
和 b
,a < b
和 b < a
都为真,而它们本应为假。
由于您违反了 std::map
的合同,因此行为未定义。
是因为你的operator<
实现不正确。这是正确的版本:
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;
}
基本上就是说,如果 x
相等,则比较 y
,如果太相等,则比较 z
。
一个较短的实现可能是这样的:
bool operator<(const Foo& other) const {
return std::tie(x, y,z) < std::tie(other.x, other.y, other.z);
}
希望对您有所帮助。