C ++将Rvalue引用传递给采用左值引用的函数

时间:2016-12-19 05:40:43

标签: function c++11 rvalue-reference

当我在阅读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)对吗?他们怎么能相互匹配?

如果带有左值引用类型参数的函数可以使用右值引用传递,则此函数可以执行任何想要甚至修改传入的右值(如临时对象)的操作。这对我来说没有意义......

1 个答案:

答案 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传递给你的函数。