Home > Back-end >  Using curly brackets instead of make_pair giving error
Using curly brackets instead of make_pair giving error

Time:10-03

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.

  • Related