make_tuple with template parameters does not compile

c++, c++11, rvalue-reference, tuples

Solution

`std::make_tuple` and `std::make_pair` are designed to deduce template parameters (among other things, like unpacking reference wrappers). Providing them explicitly is a mistake.

In this particular case, it's because template deduction for rvalues yields their type, analogous to this example:

template<typename T>
void foo(T&&);

foo(42); // foo<int>(int&&)
int i{};
foo(i); // foo<int&>(int&) // after reference collapsing

and that's why `make_tuple<int>(...)` wants a rvalue reference to its argument.

If you want to force conversions, all you need to say is

auto tup1 = std::tuple<long>(i);

Problem

Consider this code: ``` #include <tuple> int main() { int i; long k; auto tup1 = std::make_tuple<long>(i); // Compiles auto tup2 = std::make_tuple<int>(k); // Compiles auto tup3 = std::make_tuple<int>(i); // Does not compile auto tup4 = std::make_tuple<int>(i+0); // Compiles auto tup5 = std::make_tuple(i); // Compiles } ``` Why does `auto tup3 = ...` not compile? Apparently, `make_tuple<int>(...)` wants an rvalue reference as its argument; but why? (I'm using GCC 6.1.0.)

Original source