通用引用的 standard/official 名称是什么?
What's the standard/official name for universal references?
我知道如果某个变量或参数被声明为 T&&
某些推导类型 T
,则该变量或参数被广泛称为 通用引用 .
术语通用参考 是由 Scott Meyers 在他最初的演讲 “Universal References in C++11” 中引入的。但是,我想知道 通用引用 的 official/standard 术语是什么。
概览
众所周知,自 C++11 起,T&&
类型的参数称为 rvalue 引用 [ISO/IEC 14882:2011 §8.3.2/p2 参考资料 [dcl.ref] ]。也就是说,除非 T
是模板参数类型或 auto
或某个左值引用类型的 typedef
。
examples:
template<typename T>
void foo(T&& p) { // -> T is a template parameter
...
}
auto &&p = expression;
尽管从技术上讲,上述示例中的 T&&
仍然是右值引用,但其行为与常规引用有很大不同。
自然会问 "why this special case doesn't have a special syntax"。答案是 &&
语法是 C++ 委员会故意为这个特殊结构重载的。但是,他们没有为这种特殊情况命名。
在没有这个特定结构的独特名称的情况下,Scott Meyers coined the widely known term/name universal references。
然而,出于多种原因,委员会认为这个名称不合适。因此,提案 N4164 made by Herb Sutter, Bjarne Stroustrup and Gabriel Dos Reis 建议将名称更改为 Forwarding References。
名称转发参考文献 在委员会成员(包括前面提到的提案的作者)的非正式讨论中获得最多支持。有趣的是,正是 Scott Meyers 本人在他最初的“通用参考”演讲中引入了该术语。然而,后来他决定使用 universal references 这个名字。对于这个决定起作用的事实是,当时他不认为 转发引用 一词还包括 auto&&
案例。
为什么不通用引用?
根据提议,通用引用这个词虽然是一个合理的名字,意思也很明显,但在几个方面恰好是错误的。
一个通用参考必须表示如下:
- 随处可用的参考;或
- 万物皆可参考;或
- 类似的东西。
显然,情况并非如此,这种结构的使用也不恰当。此外,这个名称会鼓励许多人认为具有这样名称的东西是要使用的 "universally"。委员会认为这是一件坏事。
此外,"universal references"甚至都不是
引用本身,而是一组规则,用于在特定上下文中以特定方式使用引用,并具有对该用途的某种语言支持,并且该用途是转发。
为什么 auto&&
也被视为转发案例
auto&&
也被认为是前向案例,因为它遵循 reference collapsing rules。例如:
- 形式为
[](auto&& x){ … }
的通用 lambda
for
-形式的范围循环,for(auto &&i : v) { ... }
- 最后,总的来说
auto&&
局部变量是为了转发
转发引用的标准措辞
术语转发引用在draft standard N4527中的以下位置被提及:
§14.8.2.1/ 从函数调用中推导模板参数 [temp.deduct.call] (强调我的):
If P is a cv-qualified type, the top level cv-qualifiers of P’s type
are ignored for type deduction. If P is a reference type, the type
referred to by P is used for type deduction. A forwarding
reference is an rvalue reference to a cv-unqualified template
parameter. If P is a forwarding reference and the argument is an
lvalue, the type “lvalue reference to A” is used in place of A for
type deduction. [ Example:
template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i); // calls f<int&>(int&)
int n2 = f(0); // calls f<int>(int&&)
int n3 = g(i); // error: would call g<int>(const int&&), which
// would bind an rvalue reference to an lvalue
— end example ]
§14.8.2.5/p10 从类型推导模板参数 [temp.deduct.type]:
Similarly, if P has a form that contains (T), then each parameter type
Pi of the respective parameter-typelist of P is compared with the
corresponding parameter type Ai 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 Pi and Ai are parameters of the
top-level parameter-type-list of P and A, respectively, Pi is adjusted
if it is a forwarding reference (14.8.2.1) and Ai is an lvalue
reference, in which case the type of Pi is changed to be the template
parameter type (i.e., T&& is changed to simply T). [ Note: As a
result, when Pi is T&&
and Ai is X&
, the adjusted Pi will be T,
causing T to be deduced as X&
. — end note ] [Example:
template <class T> void f(T&&);
template <> void f(int&) { } // #1
template <> void f(int&&) { } // #2
void g(int i) {
f(i); // calls f<int&>(int&), i.e., #1
f(0); // calls f<int>(int&&), i.e., #2
}
— end example ] If the parameter-declaration corresponding to Pi is a
function parameter pack, then the type of its declaratorid is compared
with each remaining parameter type in the parameter-type-list of A.
Each comparison deduces template arguments for subsequent positions in
the template parameter packs expanded by the function parameter pack.
During partial ordering (14.8.2.4), if Ai was originally a function
parameter pack:
我知道如果某个变量或参数被声明为 T&&
某些推导类型 T
,则该变量或参数被广泛称为 通用引用 .
术语通用参考 是由 Scott Meyers 在他最初的演讲 “Universal References in C++11” 中引入的。但是,我想知道 通用引用 的 official/standard 术语是什么。
概览
众所周知,自 C++11 起,T&&
类型的参数称为 rvalue 引用 [ISO/IEC 14882:2011 §8.3.2/p2 参考资料 [dcl.ref] ]。也就是说,除非 T
是模板参数类型或 auto
或某个左值引用类型的 typedef
。
examples:
template<typename T> void foo(T&& p) { // -> T is a template parameter ... } auto &&p = expression;
尽管从技术上讲,上述示例中的 T&&
仍然是右值引用,但其行为与常规引用有很大不同。
自然会问 "why this special case doesn't have a special syntax"。答案是 &&
语法是 C++ 委员会故意为这个特殊结构重载的。但是,他们没有为这种特殊情况命名。
在没有这个特定结构的独特名称的情况下,Scott Meyers coined the widely known term/name universal references。
然而,出于多种原因,委员会认为这个名称不合适。因此,提案 N4164 made by Herb Sutter, Bjarne Stroustrup and Gabriel Dos Reis 建议将名称更改为 Forwarding References。
名称转发参考文献 在委员会成员(包括前面提到的提案的作者)的非正式讨论中获得最多支持。有趣的是,正是 Scott Meyers 本人在他最初的“通用参考”演讲中引入了该术语。然而,后来他决定使用 universal references 这个名字。对于这个决定起作用的事实是,当时他不认为 转发引用 一词还包括 auto&&
案例。
为什么不通用引用?
根据提议,通用引用这个词虽然是一个合理的名字,意思也很明显,但在几个方面恰好是错误的。
一个通用参考必须表示如下:
- 随处可用的参考;或
- 万物皆可参考;或
- 类似的东西。
显然,情况并非如此,这种结构的使用也不恰当。此外,这个名称会鼓励许多人认为具有这样名称的东西是要使用的 "universally"。委员会认为这是一件坏事。
此外,"universal references"甚至都不是 引用本身,而是一组规则,用于在特定上下文中以特定方式使用引用,并具有对该用途的某种语言支持,并且该用途是转发。
为什么 auto&&
也被视为转发案例
auto&&
也被认为是前向案例,因为它遵循 reference collapsing rules。例如:
- 形式为
[](auto&& x){ … }
的通用 lambda
for
-形式的范围循环,for(auto &&i : v) { ... }
- 最后,总的来说
auto&&
局部变量是为了转发
转发引用的标准措辞
术语转发引用在draft standard N4527中的以下位置被提及:
§14.8.2.1/ 从函数调用中推导模板参数 [temp.deduct.call] (强调我的):
If P is a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction. A forwarding reference is an rvalue reference to a cv-unqualified template parameter. If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction. [ Example:
template <class T> int f(T&& heisenreference); template <class T> int g(const T&&); int i; int n1 = f(i); // calls f<int&>(int&) int n2 = f(0); // calls f<int>(int&&) int n3 = g(i); // error: would call g<int>(const int&&), which // would bind an rvalue reference to an lvalue
— end example ]
§14.8.2.5/p10 从类型推导模板参数 [temp.deduct.type]:
Similarly, if P has a form that contains (T), then each parameter type Pi of the respective parameter-typelist of P is compared with the corresponding parameter type Ai 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 Pi and Ai are parameters of the top-level parameter-type-list of P and A, respectively, Pi is adjusted if it is a forwarding reference (14.8.2.1) and Ai is an lvalue reference, in which case the type of Pi is changed to be the template parameter type (i.e., T&& is changed to simply T). [ Note: As a result, when Pi is
T&&
and Ai isX&
, the adjusted Pi will be T, causing T to be deduced asX&
. — end note ] [Example:template <class T> void f(T&&); template <> void f(int&) { } // #1 template <> void f(int&&) { } // #2 void g(int i) { f(i); // calls f<int&>(int&), i.e., #1 f(0); // calls f<int>(int&&), i.e., #2 }
— end example ] If the parameter-declaration corresponding to Pi is a function parameter pack, then the type of its declaratorid is compared with each remaining parameter type in the parameter-type-list of A. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. During partial ordering (14.8.2.4), if Ai was originally a function parameter pack: