C++通用引用和LRef参数的类型推导
C++ Universal Reference and type deduction of LRef parameter
假设我们有一些代码
template <typename T>
void Foo(T&& param);
int x = 5;
// deduced Foo<int&>(int&).
// Argument type A = int. T = int&.
Foo(x);
int& rx = x;
// deduced Foo<int&>(int& &&) -> Foo<int&>(int&).
// But... argument type A = int&, an lvalue reference to int.
// Is T = int& or under the hood it is T = int& &?
Foo(rx);
根据https://en.cppreference.com/w/cpp/language/template_argument_deduction
4) If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction
我想知道的是:'reference collapsing' 规则是否应用于推导类型 T(而不是 P,参数类型)?
所以我们真的有 'Foo(rx)' T = int& &,它折叠成 T = int&?
请注意,实际上,出于所有技术目的,表达式的类型永远不会被视为引用类型。 [expr.type]/1:
If an expression initially has the type "reference to T
" ([dcl.ref], [dcl.init.ref]), the type is adjusted to T
prior to any further analysis.
一个值得注意的例外是当 decltype()
应用于未加括号的名称或 class 成员访问表达式时。尽管语法将名称视为表达式,但语义结果涉及名称的声明类型 而不是 表达式的类型和值类别。
因此在您的示例中,x
是类型 int
的左值,而 rx
是类型 int
的左值。在它们的声明和初始化之后,语言对它们没有任何区别,除非你再次使用 decltype(x)
或 decltype(rx)
.
这意味着 Foo(rx)
的模板类型推导与 Foo(x)
的工作方式完全相同:类型 A
是 int
,而不是 int&
,参数是左值。根据您引用的规则,T
被推断为 int&
,并且当将 T=int&
代入函数类型时,引用折叠规则表明 T&&
是 int&
.
假设我们有一些代码
template <typename T>
void Foo(T&& param);
int x = 5;
// deduced Foo<int&>(int&).
// Argument type A = int. T = int&.
Foo(x);
int& rx = x;
// deduced Foo<int&>(int& &&) -> Foo<int&>(int&).
// But... argument type A = int&, an lvalue reference to int.
// Is T = int& or under the hood it is T = int& &?
Foo(rx);
根据https://en.cppreference.com/w/cpp/language/template_argument_deduction
4) If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction
我想知道的是:'reference collapsing' 规则是否应用于推导类型 T(而不是 P,参数类型)?
所以我们真的有 'Foo(rx)' T = int& &,它折叠成 T = int&?
请注意,实际上,出于所有技术目的,表达式的类型永远不会被视为引用类型。 [expr.type]/1:
If an expression initially has the type "reference to
T
" ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis.
一个值得注意的例外是当 decltype()
应用于未加括号的名称或 class 成员访问表达式时。尽管语法将名称视为表达式,但语义结果涉及名称的声明类型 而不是 表达式的类型和值类别。
因此在您的示例中,x
是类型 int
的左值,而 rx
是类型 int
的左值。在它们的声明和初始化之后,语言对它们没有任何区别,除非你再次使用 decltype(x)
或 decltype(rx)
.
这意味着 Foo(rx)
的模板类型推导与 Foo(x)
的工作方式完全相同:类型 A
是 int
,而不是 int&
,参数是左值。根据您引用的规则,T
被推断为 int&
,并且当将 T=int&
代入函数类型时,引用折叠规则表明 T&&
是 int&
.