C++:为什么 returns false 的集合顺序的函子只允许将一个元素添加到集合中?

C++: Why does a functor for set order which returns false only lets one element be added to the set?

我编写了以下仿函数,希望集合中的所有元素都按插入的相反顺序添加:

struct cmp {
  bool operator () (int a, int b) {
    return false;
  }
};  

当我如下测试时,添加到集合中的唯一值是 1。

int main() {
  set<int, cmp > combos;

  combos.insert(1);
  combos.insert(4);
  combos.insert(7);
  combos.insert(5);
  combos.insert(9);
  combos.insert(1);

  for (int a : combos) {
    cout << a << endl;
  }
  return 0;
}

但是,当我每次将仿函数更改为 return true 时,所有值都会按照插入的顺序添加到集合中 [1, 4, 7, 5, 9, 1]。我以为当函子比较器returns true时,就好像第一个元素比第二个元素小,false的意思是第一个元素比第二个元素大?我在operator函数里做return (a < b);return (a > b);好像是这样。

在这种情况下,std::set 使用 !(a < b) && !(b < a) 来确定两个元素是否相等:ab

!(false) && !(false) 每次检查重复项时都会产生 true,因此不允许 std::set 包含多个元素。这是对std::set.

的虐待

比较函数需要对元素定义严格的弱序。即这三个条件需要对所有元素都成立,a, b, c:

  1. a < afalse(非自反性)
  2. a < btrue 意味着 b < afalse(不对称)
  3. a < bb < ctrue 意味着 a < c 也是 true(传递性)

当使用比较器对象时 cmp 上面的条件需要应用 x < y 替换为 cmp(x, y)

您的第一个比较函数(总是 returning false)实际上是一个严格的弱顺序,然而,它暗示所有元素都是等价的。无法区分两个元素。特别是,a < bb < a 都不会产生 true。如果这两个条件都是 false ,那么这两个对象显然是等价的。结果,集合中只有一个元素。

第二个比较函数(总是return true)不是严格的弱序,因为它违反了第一个条件(非自反性)。集合中发生的任何事情都是未定义的行为。