为什么运营商< of c ++ map不能与< =一起使用

时间:2018-03-21 02:36:39

标签: c++ stl

我有以下带有自定义键的地图程序:

class MyClass
{
public:

    MyClass(int i): val(i) {}

    bool operator< (const MyClass& that) const { return val <= that.val; }

private:
    int val;
};

int main()
{
    MyClass c1(1);
    MyClass c2(2);
    MyClass c3(3);

    map<MyClass, int> table;

    table[c1] = 12;
    table[c2] = 22;
    table[c3] = 33;

    cout << "Mapped values are: " << table.lower_bound(c1)->second << " " << table[c2] << " " << table[c3] << endl;

}

输出如下:

Mapped values are: 22 0 0

但如果我使用&lt;比较或者&gt;在运营商中&lt;而不是&lt; =然后一切正常。输出如下:

Mapped values are: 12 22 33

有人可以解释为什么&lt; =根本不起作用,但是&lt;甚至&gt;作品?

2 个答案:

答案 0 :(得分:7)

std::map使用的比较函数必须实现strict weak ordering。这意味着它必须在给定对象xyz的情况下实施以下规则:

  • op(x, x)必须始终为假
  • 如果op(x, y)为真,则op(y, x)必须为false
  • 如果op(x, y) && op(y, z)为真,那么op(x, z)也必须为真
  • 如果!op(x, y) && !op(y, x)为真,那么!op(x, z) && !op(z, x)也必须为真

<=运算符不满足这些条件,因为给定x = y = 1x <= x不为假,x <= yy <= x都为真。

std::map使用这些规则来实现其比较。例如,它可以将等式检查实现为!(op(x, y) || op(y, x))。鉴于x = 4y = 4op = operator<=,这变为!(4 <= 4 || 4 <= 4),因此44的比较不等,因为上面的第一条规则被打破了

答案 1 :(得分:1)

cppreference上我们找到了这个引用。

  

标准库的所有地方都使用Compare概念,唯一性由等价关系决定。不精确的说,如果两个对象的比较小于另一个,则认为两个对象a和b是等价的(不是唯一的):!comp(a,b)&amp;&amp; !comp(b,a)。

这意味着你当前比较

bool operator< (const MyClass& that) const { return val <= that.val; }

如果您有两个MyClass {5}和5 val5 <= 5将返回true,并且它们不会被视为等效。