It gives no instance of overloaded function "lower_bound" matches the argument list
error. I don't understand this behavior as curly brackets work fine in general while making a pair.
Using curly brackets:
vector<pair<int, int>> a;
auto ptr = lower_bound(a.begin(), a.end(), {2, 3});
Using make pair:
vector<pair<int, int>> a;
auto ptr = lower_bound(a.begin(), a.end(), make_pair(2, 3));
CodePudding user response:
Compiler has no possiblility to deduce {2, 3}
to std::pair<int, int>
in this context. See the declaration of lower_bound
:
template< class ForwardIt, class T >
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value );
Compiler cannot assume that T
should be equal to decltype(*first)
, because it doesn't have to be the case - it's only required that they are comparable.
You need to disambiguate by actually naming the type you want to use - either by calling std::make_pair(2, 3)
or by creating a temporary: std::pair{2, 3}
(template arguments can be ommitted since C 17, for earlier standard you need std::pair<int, int>{2, 3}
or make_pair
).
CodePudding user response:
The answer provided by Yksisarvinen explains why your first code snippet won't compile (i.e., why the compiler can't properly deduce the type of your third argument to lower_bound
); it also offers two methods to solve the issue, both of which are eminently sensible.
However, there is a third possibility – though whether or not it is 'sensible' is a subjective call. So, for the sake of completeness, I shall illustrate that method here …
You can explicitly provide the template parameters for lower_bound
in your call, which enables the compiler to correctly interpret the type of the third argument:
#include <vector>
#include <algorithm>
#include <type_traits>
using namespace std;
int main(void)
{
vector<pair<int, int>> a;
auto ptr = lower_bound< decltype(a.begin()),pair<int,int> >(a.begin(),a.end(),{2,3});
//...
return 0;
}
The following is the specification for lower_bound
(taken from cppreference):
template< class ForwardIt, class T >
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value );
Thus, in the code I have provided, we have explicitly specified the types of both ForwardIt
and class T
(as pair<int,int>
), so the third function argument will be known to be a const
reference to such a type, and deduction of that type will not be required.