3

For C++98

template <class T1, class T2>
  pair<T1,T2> make_pair (T1 x, T2 y);

For C++11

template <class T1, class T2>
  pair<V1,V2> make_pair (T1&& x, T2&& y);  // see below for definition of V1 and V2

If T1 and/or T2 are rvalue references, the objects are moved and x and/or y are left in an undefined but valid state.

// make_pair example
#include <utility>      // std::pair
#include <iostream>     // std::cout
#include <functional>
#include <unordered_set>
using namespace std;

int main () {
  int i = 2;
  int j = 3;

  pair<int, int> p0 = make_pair<int, int>(2, 3); // fine
  pair<int, int> p1 = make_pair<int, int>(move(i), move(j)); // fine
  pair<int, int> p2 = make_pair<int, int>(i+0, j+0); // fine
  pair<int, int> p3 = pair<int, int>(i, j); // fine

  const int i2 = 2;
  const int j2 = 3;
  // error: no matching function for call to ‘make_pair(const int&, const int&)’
  pair<int, int> p4 = make_pair<int, int>(i2, j2); // wrong

  // error: no matching function for call to ‘make_pair(int&, int&)’
  pair<int, int> p5 = make_pair<int, int>(i, j); // wrong

  return 0;
}

Question> I found that it is inconvenient to create a pair with non-rvalue reference variables by make_pair. As you can see above code, the following line doesn't compile.

  // error: no matching function for call to ‘make_pair(int&, int&)’
  pair<int, int> p4 = make_pair<int, int>(i, j); // wrong

In practice, how do you make use of make_pair with non-rvalue reference variables?

Thank you

q0987
  • 34,938
  • 69
  • 242
  • 387
  • 2
    Just use `make_pair(i, j)` without explicitly specifying the type parameters. The compiler will infer `int&` for the type parameters if you pass lvalue references. – nosid Jun 28 '14 at 20:55
  • Note that the parameters of `make_pair` are *universal references*. – dyp Jun 28 '14 at 21:30
  • also passing a lvalue (reference) would result in a lvalue reference, not rvalue reference. It would be copied, not moved. See https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers for more details – SwiftMango Jun 28 '14 at 21:31
  • @dyp I believe they call it that... but it is rvalue reference by standard, although deduction may not result in a rvalue reference but lvalue reference – SwiftMango Jun 28 '14 at 21:32
  • @texasbruce It's a language hack; I call that feature *universal reference* (Scott Meyers invented that term). It's a term you can easily search for, and less confusing (in my experience) than talking about rvalue references plus reference collapsing. Names are important. – dyp Jun 28 '14 at 21:34

2 Answers2

7

The point of std::make_pair is to deduce type of your arguments for you. Otherwise you could just write:

auto p = std::pair<int, double>(42, -1.5);

Instead, you write

auto p = std::make_pair(42, -1.5);
milleniumbug
  • 15,379
  • 3
  • 47
  • 71
2

You asked:

In practice, how do you make use of make_pair with non-rvalue reference variables?

You can use:

auto p4 = make_pair(i2, j2); 
auto p5 = make_pair(i, j); 
R Sahu
  • 204,454
  • 14
  • 159
  • 270