make_tuple 带模板参数不编译
make_tuple with template parameters does not compile
考虑这段代码:
#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
}
为什么auto tup3 = ...
编译不通过?显然,make_tuple<int>(...)
想要一个右值引用作为它的参数;但是为什么?
(我使用的是 GCC 6.1.0。)
std::make_tuple
和 std::make_pair
旨在推断模板参数(除其他外,如解包引用包装器)。明确提供它们是错误的。
在这种特殊情况下,这是因为右值的模板推导会产生它们的类型,类似于此示例:
template<typename T>
void foo(T&&);
foo(42); // foo<int>(int&&)
int i{};
foo(i); // foo<int&>(int&) // after reference collapsing
这就是为什么 make_tuple<int>(...)
需要对其参数的右值引用。
如果你想强制转换,你只需要说
auto tup1 = std::tuple<long>(i);
考虑这段代码:
#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
}
为什么auto tup3 = ...
编译不通过?显然,make_tuple<int>(...)
想要一个右值引用作为它的参数;但是为什么?
(我使用的是 GCC 6.1.0。)
std::make_tuple
和 std::make_pair
旨在推断模板参数(除其他外,如解包引用包装器)。明确提供它们是错误的。
在这种特殊情况下,这是因为右值的模板推导会产生它们的类型,类似于此示例:
template<typename T>
void foo(T&&);
foo(42); // foo<int>(int&&)
int i{};
foo(i); // foo<int&>(int&) // after reference collapsing
这就是为什么 make_tuple<int>(...)
需要对其参数的右值引用。
如果你想强制转换,你只需要说
auto tup1 = std::tuple<long>(i);