我有以下代码。
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 argumentTT
or a template non-type argumenti
can be deduced ifP
andA
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 typeP<sub><em>i</em></sub>
of the respective parameter-type-list ofP
is compared with the corresponding parameter typeA<sub><em>i</em></sub>
of the corresponding parameter-type-list ofA
. IfP
andA
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) andP<sub><em>i</em></sub>
andA<sub><em>i</em></sub>
are parameters of the top-level parameter-type-list ofP
andA
, respectively,P<sub><em>i</em></sub>
is adjusted if it is an rvalue reference to a cv-unqualified template parameter andA<sub><em>i</em></sub>
is an lvalue reference, in which case the type ofP<sub><em>i</em></sub>
is changed to be the template parameter type (i.e.,T&&
is changed to simplyT
). [...]
和
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 toA
" is used in place ofA
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/