当我在阅读Effective Modern C++ by Scott Meyer关于std :: forward函数如何工作时,我得到了一个我不太了解的问题。假如我们有一个函数foo
,如下所示:
template<typename T>
void foo(T&& fooParam)
{
...
someFunc(std::forward<T>(fooParam));
}
在书中,Scott解释说std::forward<T>
可以通过以下方式实现:
template<typename T>
T&& forward(typename remove_reference<T>::type& param)
{
return static_cast<T&&>(param);
}
假设传递给foo
的参数是Widget
类型的右值。然后std::forward
函数模板将初始化为:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
所以我的问题是,当fooParam
(类型为Widget &&
)传递给std::forward
时,采用Widget& param
类型参数的函数如何匹配{ {1}}?我知道fooParam
本身就是左值。但它的类型仍然是右值引用(fooParam
)对吗?他们怎么能相互匹配?
如果带有左值引用类型参数的函数可以使用右值引用传递,则此函数可以执行任何想要甚至修改传入的右值(如临时对象)的操作。这对我来说没有意义......
答案 0 :(得分:2)
#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;
}
正如你所说,r_ref是左值引用,你不应该把它作为右值引用匹配。如果你想把参数作为右值引用,使用std::move()
或者只是将rvalue传递给你的函数。