为什么右值引用类型的模板参数可以绑定到左值类型?

Pei*_*ung 2 c++ forwarding-reference

据我所知,右值引用不能绑定到左值。例如,

\n\n
void func(Foo &&f) {}\nint main() {\n Foo f;\n func(f);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器抱怨:\n 错误:无法将 \xe2\x80\x98Foo&&\xe2\x80\x99 类型的右值引用绑定到 \xe2\x80\x98Foo 类型的左值

\n\n

但是,为什么右值引用类型的模板参数可以绑定到左值?\ne.g.

\n\n
template <typename T> void funcTemp(T &&arg) {}\nint main() {\n Foo f;\n funcTemp(f);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器不会报告该错误。\n为什么?

\n

Yol*_*ola 5

你可以阅读这篇文章Universal References in C++11来理解。这是其中的一部分:

\n\n
\n

如果变量或参数被声明为具有某些推导类型的类型T&&,则该变量或参数是通用引用。

\n\n
Widget&& var1 = someWidget;      // here, \xe2\x80\x9c&&\xe2\x80\x9d means rvalue reference\n\nauto&& var2 = var1;              // here, \xe2\x80\x9c&&\xe2\x80\x9d does not mean rvalue reference\n\ntemplate<typename T>\nvoid f(std::vector<T>&& param);  // here, \xe2\x80\x9c&&\xe2\x80\x9d means rvalue reference\n\ntemplate<typename T>\nvoid f(T&& param);               // here, \xe2\x80\x9c&&\xe2\x80\x9ddoes not mean rvalue reference\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

以下是与您的案例相关的标准摘录

\n\n
\n

... 函数模板参数类型(称之为 P) ... 如果 P 是转发引用并且参数是左值,则使用对 A\xe2\x80\x9d 的类型 \xe2\x80\x9clvalue 引用来代替A 用于类型推导。

\n
\n