0

cpprefernce says:

template< class ForwardIt, class T, class Compare > ForwardIt
upper_bound( ForwardIt first, ForwardIt last, const T& value, compare comp );

(...)

comp - comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than the second. The signature of the comparison function should be equivalent to the following:

bool cmp(const Type1 &a, const Type2 &b);

(...) The type Type1 must be such that an object of type T can be implicitly converted to Type1. The type Type2 must be such that an object of type ForwardIt can be dereferenced and then implicitly converted to Type2.

Having the following piece of code:

#include <algorithm>
#include <string>
#include <vector>

using namespace std;

struct employee {
  string first;
  string last;
};

int main() {
  vector<employee> v = { {"John", "Smith"} };

  sort(v.begin(), v.end(),
       [](const employee& e1, const employee& e2) { return e1.last < e2.last; });

  auto p = lower_bound(v.begin(), v.end(), "Smith",
                       [](const employee& e, const string& y) { return e.last < y; });
}

and the Possible implementation from cppreference:

template<class ForwardIt, class T, class Compare>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    ForwardIt it;
    typename std::iterator_traits<ForwardIt>::difference_type count, step;
    count = std::distance(first,last);

    while (count > 0) {
        it = first; 
        step = count / 2;
        std::advance(it, step);
        if (!comp(value, *it)) {
            first = ++it;
            count -= step + 1;
        } else count = step;
    }
    return first;
}

The parameters' order in lambda passed to lower_bound's call should be reversed since value is a const std::string& and it's passed to comp as first parameter, yet it compiles like this and gives a compilation error if passed differently.

What am I missing here?

Patryk
  • 22,602
  • 44
  • 128
  • 244

0 Answers0