带模板参数的make_tuple无法编译

oz1*_*1cz 4 c++ tuples rvalue-reference c++11

考虑以下代码:

#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
}
Run Code Online (Sandbox Code Playgroud)

为什么不auto tup3 = ...编译?显然,make_tuple<int>(...)想要一个右值引用作为其参数; 但为什么?

(我正在使用GCC 6.1.0.)

krz*_*zaq 7

std::make_tuple并且std::make_pair旨在推导模板参数(除其他外,如解包参考包装器).明确地提供它们是一个错误.

在这种特殊情况下,这是因为rvalues的模板推导产生了它们的类型,类似于这个例子:

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

foo(42); // foo<int>(int&&)
int i{};
foo(i); // foo<int&>(int&) // after reference collapsing
Run Code Online (Sandbox Code Playgroud)

这就是为什么make_tuple<int>(...)要对其参数进行右值引用.

如果你想强制转换,你需要说的就是

auto tup1 = std::tuple<long>(i);
Run Code Online (Sandbox Code Playgroud)