了解返回时的右值参考

时间:2018-06-01 21:08:04

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

例如我有代码,如下面的

//g++  5.4.0

#include <iostream>

struct data
{
    int n;
    data()
    {
        std::cout << "data()\n";
    }
    data(const data&)
    {
        std::cout << "data(const data&)\n";
    }
    data(data&&)
    {
        std::cout << "data(data&&)\n";
    }
};

class container
{
    data d;    
public:
    data getData()
    {
        return std::move(d);
    }
};

int main()
{
    container c;
    data result = c.getData();
}

输出是:

data() 
data(data&&)

我不明白它是如何运作的。我没有将返回类型声明为data&&,但移动构造函数可以正常工作。是的,代码为std::move(d),但返回类型不是data&&。那么它是怎样工作的?

2 个答案:

答案 0 :(得分:4)

此答案在中有所改变。

data getData()
{
    return std::move(d);
}

此方法将d移动到其返回值。

data x = foo.getData();

这个从x的返回值构造getData。但是,如果getData返回prvalue(匹配的值类型),则C ++标准鼓励并允许此构造 elided 。 Elision意味着合并返回值<{1}}的标识生存期。只存在一个对象,而不是两个。

这允许跳过副作用,比如移动构造函数中的print语句。

所以x是移动的对象,并且该移动直接构造d

如果您更改x以返回getData,则现在data&&内没有移动,但在构建getData时,一个移动完成。

中,x的返回值绝不是对象,它是prvalue,中的prvalues更像是创建对象的指令。实际上,省略不再是可选的。

答案 1 :(得分:3)

如果返回类型设置为data(如您的情况),则返回的对象是prvalue。 如果返回类型设置为data&&,则返回的对象为xrvalue。

在任何一种情况下,返回的对象都是右值,并且将调用result的移动构造函数。

另请参阅:http://stackoverflow.com/a/10159163/4509057