C++,为什么 std::set 允许 lower_bound() 在不同于集合元素的类型上,但前提是我在集合声明中添加 less<> ?

C++, why does std::set allow lower_bound() on a type different than that of the set elements, but only if I add less<> in the set declaration?

我有这个 class 和一个过载的比较器:

struct Foo {
    int x;
    bool operator < (Foo other) const {
        return x < other.x;
    }
    bool operator < (int val) const {
        return x < val;
    }
};

然后我在上面做了一套:

set<Foo> s;

我可以在 Foo 上调用 lower_bound(),但不能在 int 上调用(如您所料)。

s.lower_bound(Foo{3}); // works
s.lower_bound(3); //"no matching member function for call to 'lower_bound'

但是如果我用 less<> 声明 s :

set<Foo,less<>>

两个调用都有效:

s.lower_bound({3});
s.lower_bound(3);

为什么?

why does std::set allow lower_bound() on a type different than that of the set elements

因为它很有用,而且可能更有效率。

考虑一组 std::string 的例子。创建(大)字符串很昂贵。如果您有字符串视图,则可以使用 std::less<> 将该视图与集合的字符串进行比较,而无需从该视图构造字符串。

but only if I add less<> in the set declaration?

因为您将 std::less<> 作为参数传递给的第二个类型参数是集合用来比较元素的函子。 std::less<> 能够比较不同类型的对象。默认比较器是 std::less<T>,它只能比较类型 T 的对象。 std::less<> 不是默认值,因为在标准化 std::set 时它不存在。