1

I am newbie in C++ and I am trying to use lower_bound and upper_bound for sorting and searching vector. This line of code make strange error for me:

up = upper_bound(low, this->data.end(), name, [](const human & a, const string & b) {return (a.name < b) ? true : false;});

The error is no matching function call to object of type <lambda at ... which is not fired on this line, but in algorithm library on line 4104. I am confused, because I am using upper_bound in another part of code it works fine. Also when I changed the function from upper_bound to lower_bound everything works fine.

Does anyone has idea how to solve that?

juan.facorro
  • 9,791
  • 2
  • 33
  • 41
Jakub Pexa
  • 13
  • 1
  • 4
  • 1
    Please post an [MCVE](http://stackoverflow.com/help/mcve) along with the full compiler error and use the code formatting button to format your code. – chris Mar 22 '14 at 15:16
  • 1
    Unrelated, but remember that the expression `a.name < b` already is a boolean `true` or `false`, so no need for the ternary condition. – Some programmer dude Mar 22 '14 at 15:18
  • this link will help you out:http://stackoverflow.com/questions/4268848/c-lambdas-for-stdsort-and-stdlower-bound-equal-range-on-a-struct-element-i – jfly Mar 22 '14 at 15:34

2 Answers2

3

When using mixed type comparisons you need to be rather careful which argument goes where. According to the standard (25.4.3.2 [upper.bound] paragraphs 1 and 2), the comparisons done are comp(value, *it) where value is the third argument to std::upper_bound(). You don't show enough code but based on the signature I'd guess you need to change the order of the arguments. Using the following lambda should work:

[](std::string const& name, human const& object) {
    return name < object.name;
};

It is worth noting that std::lower_bound() expects the arguments in the opposite order (25.4.3.1 [lower.bound] paragraphs 1 and 2). That the lambda you have, indeed, should work for std::lower_bound()!

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 1
    Instead of using mixed type comparisons, I recommend using [std::partition_point](http://en.cppreference.com/w/cpp/algorithm/partition_point). – nosid Mar 22 '14 at 15:33
  • Thanks a lot! It solved my problem. I split the arguments and everything works fine. Sorry about just one line of the code, but this is homework to school and we can't show our solutions on web. – Jakub Pexa Mar 22 '14 at 15:43
  • It is entirely viable to create an excerpt showing the problem! I tested my solution with ~15 lines of code (including all headers, line breaks, etc.). – Dietmar Kühl Mar 22 '14 at 16:09
0

It seems that the problem is that inside the body of the algorithm there is used the following expression

!Predicate( value, *iterator )

As your class has no conversion function that would convert an object of type std::string to an object of type humen or from an object of type type human to an object of type std::string then the compiler issue the error.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335