Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make_tuple with template parameters does not compile

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.)

like image 445
oz1cz Avatar asked Mar 11 '23 19:03

oz1cz


1 Answers

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);
like image 197
krzaq Avatar answered Mar 20 '23 17:03

krzaq