我有以下带有自定义键的地图程序:
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;作品?
答案 0 :(得分:7)
std::map
使用的比较函数必须实现strict weak ordering。这意味着它必须在给定对象x
,y
和z
的情况下实施以下规则:
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 = 1
,x <= x
不为假,x <= y
和y <= x
都为真。
std::map
使用这些规则来实现其比较。例如,它可以将等式检查实现为!(op(x, y) || op(y, x))
。鉴于x = 4
,y = 4
和op = operator<=
,这变为!(4 <= 4 || 4 <= 4)
,因此4
与4
的比较不等,因为上面的第一条规则被打破了
答案 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 val
,5 <= 5
将返回true,并且它们不会被视为等效。