c++ - 在 C++11 中推导元组元素的类型

标签 c++ c++11

我有以下代码。

template <typename... Types>
void print_tuple(const std::tuple<Types&&...>& value)
{
    std::cout << std::get<0>(value) << "," << std::get<1>(value) << std::endl;
}
print_tuple(std::forward_as_tuple("test",1));

哪个编译器提示

error: invalid initialization of reference of type ‘const std::tuple<const char (&&)[5], int&&>&’ from expression of type ‘std::tuple<const char (&)[5], int&&>’
     print_tuple(std::forward_as_tuple("test",1));

为什么编译器将元组中第一个元素的类型推断为 const char (&&)[5]?

最佳答案

一般来说,为了推导成功,参数需要与参数具有相同的一般形式。有一些异常(exception)情况 T &&可以从U &推导出来(通过选择 T = U & ),但没有为这种情况指定此类异常(exception)。

14.8.2.5 Deducing template arguments from a type [temp.deduct.type]

8 A template type argument T, a template template argument TT or a template non-type argument i can be deduced if P and A have one of the following forms:

[...]

T&
T&&

[...]

不是很清楚,但这需要P (参数)和 A (参数)都具有相同的形式。他们都需要属于 T&形式,或两者兼而有之 T&&形式。 T &&的异常情况可以从U &推导出来, 通过更改 T && 来完成平原T在匹配发生之前,在有限的情况下:

10 Similarly, if P has a form that contains (T), then each parameter type P<sub><em>i</em></sub> of the respective parameter-type-list of P is compared with the corresponding parameter type A<sub><em>i</em></sub> of the corresponding parameter-type-list of A. If P and A are function types that originated from deduction when taking the address of a function template (14.8.2.2) or when deducing template arguments from a function declaration (14.8.2.6) and P<sub><em>i</em></sub> and A<sub><em>i</em></sub> are parameters of the top-level parameter-type-list of P and A, respectively, P<sub><em>i</em></sub> is adjusted if it is an rvalue reference to a cv-unqualified template parameter and A<sub><em>i</em></sub> is an lvalue reference, in which case the type of P<sub><em>i</em></sub> is changed to be the template parameter type (i.e., T&& is changed to simply T). [...]

14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]

3 [...] If P is an rvalue reference to a cv-unqualified template parameter and the argument is an lvalue, the type "lvalue reference to A" is used in place of A for type deduction. [...]

但没有类似的异常(exception)情况适用于您的情况。

渲染也是这个原理

template <typename T> struct S { };
template <typename T> void f(S<const T>) { }
int main() { f(S<void()>()); }

无效:const T不能从 void() 推导出来, 即使 T = void()会给出准确的结果,并调用 f<void()>会成功。

Wintermute 的已删除答案表明您可以使用

template <typename... Types>       // vv-- change here
void print_tuple(const std::tuple<Types...>& value)

相反:这允许 Types根据 value 的类型推断为左值引用、右值引用或非引用.

关于c++ - 在 C++11 中推导元组元素的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29183791/

相关文章:

c++ - 将整数连接到 const char* 字符串

c++ - 内联以汇编语言编写的外部函数

c++ - 为什么这个 C++0x 代码不调用移动构造函数?

c++11 如何将遗留类转换为模板

c++ - AX 解析器生成器和 mingw gcc 4.6 运算符 &

c++ - 如何使用带有重载的enable_if

c++ - C++避免重复声明的语法是什么?

C++混淆for循环中重新声明变量的范围

c++ - 编译器不创建模板化的 ostream << 运算符

c++ - 传递多维数组给出和错误