Dre*_*mer 6 function rvalue-reference c++11
当我阅读Scott Meyer 撰写的《Effective Modern C++》,了解 std::forward 函数如何工作时,我遇到了一个我不太明白的问题。假设我们有一个foo如下函数:
template<typename T>
void foo(T&& fooParam)
{
...
someFunc(std::forward<T>(fooParam));
}
Run Code Online (Sandbox Code Playgroud)
在书中,斯科特解释说std::forward<T>可以通过以下方式实现:
template<typename T>
T&& forward(typename remove_reference<T>::type& param)
{
return static_cast<T&&>(param);
}
Run Code Online (Sandbox Code Playgroud)
假设传递给的参数foo是类型的右值Widget。然后std::forward函数模板将像这样初始化:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,当fooParam(类型为Widget &&)传递给 时,采用matchstd::forward类型参数的函数如何?我知道它本身是一个左值。但它的类型仍然是右值引用 ( ) 对吗?他们怎么可能相配呢?Widget& paramfooParamfooParamWidget &&
如果一个采用左值引用类型参数的函数可以通过右值引用传递,那么这个函数可以做任何它想做的事情,甚至修改传入的右值(就像一个临时对象)。这对我来说没有意义...
小智 7
#include <iostream>
using std::cout;
using std::endl;
template<class T>
void my_print(T&& arg)
{
my_print_impl(std::forward<T>(arg));
}
template<class T>
void my_print_impl(T& arg)
{
cout << "lvalue reference" << endl;
}
template<class T>
void my_print_impl(T&& arg)
{
cout << "rvalue reference" << endl;
}
int main()
{
int i = 1;
int & l_ref = i;
int && r_ref = 1;
my_print(l_ref); //print lvalue reference
my_print(r_ref); //print lvalue reference
my_print(std::move(l_ref)); //print rvalue reference
my_print(1); //print rvalue reference, 1 is a true rvalue
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如您所说, r_ref 是左值引用,您不应该将其作为右值引用进行匹配。如果您想将参数作为右值引用传递,请使用std::move()或仅将右值传递给您的函数。