【问题标题】:C++ Passing Rvalue Reference to Functions That Takes Lvalue ReferenceC++ 将右值引用传递给接受左值引用的函数
【发布时间】:2016-12-19 05:40:42
【问题描述】:

当我阅读Effective Modern C++ by Scott Meyer 关于 std::forward 函数如何工作的内容时,我遇到了一个我不太明白的问题。假设我们有一个函数foo,如下所示:

template<typename T>
void foo(T&& fooParam)
{
    ...
    someFunc(std::forward<T>(fooParam));
}

在书中,Scott 解释说 std::forward&lt;T&gt; 可以通过以下方式实现:

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); }

所以我的问题是,当fooParamWidget &amp;&amp; 类型)传递给std::forward 时,接受Widget&amp; param 类型参数的函数如何匹配fooParam?我知道fooParam 本身就是一个左值。但它的类型仍然是右值引用 (Widget &amp;&amp;) 对吧?他们怎么可能互相匹配?

如果一个接受左值引用类型参数的函数可以通过右值引用传递,那么这个函数可以做任何它想做的事情,甚至修改传入的右值(如临时对象)。这对我来说没有意义......

【问题讨论】:

  • 它的调用方应该关注传递 rvales 的含义。如果将右值传递给函数,则函数的调用者不应进一步使用它。但是,接收右值的函数只是将参数视为正常值。

标签: function c++11 rvalue-reference


【解决方案1】:
#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() 或者只是将右值传递给你的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2014-09-09
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多