使用非典型比较器的std :: map的奇怪行为

时间:2014-10-13 20:37:57

标签: c++ stl stdmap

让我们考虑以下代码段:

class A 
{
    public:
    int x;
    int y;
    A(int ix, int iy) : x(ix), y(iy) {}
    bool operator < (const A& a) const
    { return (x < a.x) || (y < a.y); } 
};


int main()
{
    std::map<A,int> amap;
    amap[A(0,1)] = 4;
    amap[A(1,0)] = 5;
    for(auto &x: amap)
        std::cout<<x.second<<std::endl;
    std::cout<<amap[A(0,1)]<<std::endl;
    std::cout<<amap[A(1,0)]<<std::endl;
}

输出为5 4 4 0

  • 我预计只会插入第一个元素A(0,1),但会添加两个元素。为什么?
  • 找到了第一个元素A(0,1),但第二次搜索元素A(1,0)却找不到它。为什么?

有人可以在std::map中详细解释此案例中发生的情况吗?

2 个答案:

答案 0 :(得分:2)

A a(0, 1), b(1, 0);

然后a < b && b < a。如您所见,您的订购不是不对称的。它不像a < a那样具有反射性。 所有这些都是严格弱排序的要求,每个map需要排序。没有它,您的结果很快就会变得不可预测。

答案 1 :(得分:2)

对于您插入地图的所有元素,如果a < b为true,则b < a必须为false。您的比较运算符不会这样做。

map使用树结构,并使用比较运算符完成对树的导航。如果比较运算符生成不一致的结果,则导航将丢失。