【问题标题】:Why does rvalue reference argument prefer const lvalue reference to rvalue reference parameter? [duplicate]为什么右值引用参数更喜欢 const 左值引用而不是右值引用参数? [复制]
【发布时间】:2017-01-04 07:11:58
【问题描述】:

这是VS2015中的一些代码:

class Elem 
{
public:
    Elem(int i) : a(i) {}
    Elem(Elem && other) = default;
    Elem(const Elem & other) = default;
private:
    int a;
};

int main()
{
    std::vector<Elem> vv;

    // case 0
    vv.push_back(Elem{ 0 }); // call push_back(Elem &&);

    // case 1
    Elem e1{ 1 };
    vv.push_back(e1); // call push_back(const Elem &);

    // case 2
    Elem e2{ 2 };
    auto & lref = e2;
    vv.push_back(lref); // call push_back(const Elem &);

    // case 3
    Elem e3{ 3 };
    auto && rref = std::move(e3);
    vv.push_back(rref); // call push_back(const Elem &);

    // case 4
    Elem e4{ 4 };
    vv.push_back(std::move(e4)); // call push_back(Elem &&);

    return 0;
}

情况3,rref的类型为右值引用,其值类别为lvalue,调用push_back(const Elem &amp;)

在案例 4 中,根据 Effective Modern C++ Item 23,std::move 的实现类似于

// C++ 14    
template<typename T>
decltype(auto) move(T&& param)
{
    using ReturnType = remove_reference_t<T>&&;
    return static_cast<ReturnType>(param);
}

std::move(e4)的类型为Elem &amp;&amp;,其值类别为prvalue,调用push_back(Elem &amp;&amp;)

所以T&amp;&amp;lvalue 匹配const T &amp;T&amp;&amp;prvalue 匹配T&amp;&amp;,表达式的类型和值类别在T 之间的重载解析期间实际上做了什么, const T &amp;T &amp;&amp;?


很抱歉没有清楚地描述我的问题。正如很多链接所说,如果参数的值类别是prvalue,则将调用T&amp;&amp; 的函数;值类别为lvalue,将调用const T &amp; 的函数。

我可以简单地说参数的类型用于重载解析,而当参数的类型是引用时检查值类别的引用绑定?

【问题讨论】:

标签: c++ c++11 move rvalue-reference


【解决方案1】:

rref 是一个左值,因为它有一个名字,所以 push_back(const Elem &amp;) 被调用。将move 放入命名变量中是没有用的,但如果您坚持使用它,您可以将代码更改为:

// case 3
Elem e3{ 3 };
auto && rref = std::move(e3);
vv.push_back(std::forward<decltype(e3)>(rref));

然后调用push_back(Elem &amp;&amp;)。或者只是做你在案例 4 中所做的事情。

【讨论】:

    【解决方案2】:

    当你分配一个变量名(在本例中为“e3”)并使用这个变量传入函数的那一刻,它变成了左值。这就是为什么它调用函数“push_back”的左值版本。但是当你在案例 4 中作为“std::move(e4)”传递时,它作为右值传递,这就是它调用“push_back”函数的右值引用版本的原因。

    刚刚浏览了网络,我发现这个链接以几乎相似的术语解释了右值引用。你可以查看这个链接。

    http://simpletechtalks.com/rvalue-references/

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 1970-01-01
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 2017-04-15
      • 1970-01-01
      相关资源
      最近更新 更多