I have this class with an overloaded comparator:
struct Foo {
int x;
bool operator < (Foo other) const {
return x < other.x;
}
bool operator < (int val) const {
return x < val;
}
};
and I make a set on it:
set<Foo> s;
I'm allowed to call lower_bound() on a Foo, but not on an int (as you would expect).
s.lower_bound(Foo{3}); // works
s.lower_bound(3); //"no matching member function for call to 'lower_bound'
But if instead I declare s with a less<> :
set<Foo,less<>>
Both calls work:
s.lower_bound({3});
s.lower_bound(3);
Why?
CodePudding user response:
why does std::set allow lower_bound() on a type different than that of the set elements
Because it is useful, and potentially more efficient.
Consider for example a set of std::string
s. Creating (large) strings is expensive. If you have a string view, you can use std::less<>
to compare the view to the strings of the set without having to construct a string from that view.
but only if I add less<> in the set declaration?
Because the second type parameter, to which you passed std::less<>
as the argument is the functor that the set uses to compare the elements. std::less<>
is what is able to compare objects of different types. The default comparator is std::less<T>
which can only compare objects of type T
. std::less<>
isn't the default because it didn't exist when std::set
was standardised.