这张地图有什么问题?

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。我做错了什么?

代码也在这里:http://ideone.com/fork/HMwPQ7

Foo::operator < 没有定义 std::map 所要求的 strict weak ordering
特别是,给定两个相同的 Foos aba < bb < 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

了解 Strict Weak Ordering

一个较短的实现可能是这样的:

bool operator<(const Foo& other) const {
   return std::tie(x, y,z) < std::tie(other.x, other.y, other.z);
}

希望对您有所帮助。