2

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.

0

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

7 Comments

I know that operator< is not enough for equal range or upper bound, but I don't know how it was matched for the lower bound algorithm
what if I define two overloads of a function, comp(Foo,T) and comp(T,Foo). Will that function work for the second version of the algorithms?
Lower_bound just has to compare the elements one way, like while (a < b) try_next. As soon as the comparison is false, the position has been found.
If you have two comparison operators, the code will compile. I'm not totally sure that it defines a strict weak ordering though.
I tried that, but the compiler cannot deduce which overload of comp() to use. It's not the elegant solution I was looking for anyway
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.