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.
