Reputation: 1800
I have a class that defines a strict weak ordering with other types, and I would like to use comparison-based algorithms on a container of that class (e.g. std::upper_bound).
The standard defines that the container's forward iterator value type should be that of the comparable type, so the following doesn't compile:
template<typename T>
class Foo {
public:
bool operator<(const T& _val) { return val < _val; }
//operator T() { return val; } // uncommenting this solves the problem
private:
T val;
};
void bar() {
vector<Foo<int>> foos(10);
auto i_lb = std::lower_bound(foos.begin(), foos.end(), 17); // compiles and works, though I don't know why
auto i_eq = std::equal_range(foos.begin(), foos.end(), 17); // error! not convertible to int
}
I couldn't find a way of using the algorithm version that accepts the predicate (also requires the types to be the same). Defining a conversion operator makes this example work, but it's not always right to define one. What is the right way of making such a comparison work?
Incidentally, replacing std::equal_range with std::lower_bound works, but I cannot figure out why.
Upvotes: 2
Views: 344
Reputation: 92311
The equal_range will have to compare the values both ways to determine if they are equal
A value,
a
, is considered equivalent to another,b
, when(!(a<b) && !(b<a))
lower_bound just has to find one end of the range.
You comparison just works for Foo < T
, and not for T < Foo
.
Upvotes: 3