0

我知道某个对象仅作为临时对象创建(它是库中的私有成员对象)。有时,通过将成员函数链接在一起()进一步初始化该对象TempObj().Init("param").Init("other param")。我想使用该临时实例为另一个对象启用移动构造,所以我想知道关于return std::move(*this).

struct TempObj
{
    TempObj &&Member() { /* do stuff */ return std::move(*this); }
};

struct Foo
{
    Foo(TempObj &&obj);
};

// typical usage:
Foo foo(TempObj().Member());

它在功能上等同于这个吗?

struct TempObj
{
    TempObj(TempObj &&other);
    TempObj Member() { /* do stuff */ return *this; }
};

Foo foo(TempObj().Member());
4

1 回答 1

3

使用移动语义,您不希望(或不需要)从函数返回 r-value 引用...... r-value 引用用于“捕获”未命名的值或内存地址。当您从调用者的角度返回对实际上是左值的对象的右值引用时,语义都是错误的,并且当其他人使用您的对象的方法时,您就有机会出现不必要的意外.

换句话说,最好将您的代码定向为如下所示:

Foo foo(std::move(TempObj().Member()));

并且TempObj::Member只需返回一个左值引用。这使移动变得明确,并且对于使用您对象的方法的人来说没有任何意外。

最后,不,它在功能或语义上不等同于您的上一个示例。您实际上正在制作对象的临时副本,并且该副本将是一个 r 值对象(即,在这种情况下是一个未命名的对象)......因为 r 值引用的假设是该对象是未命名的值或对象,因此它可以被传递给它的函数无害地修改,该函数采用 r 值引用参数。另一方面,如果您将对象的副本传递给函数,则该函数无法修改原始对象。它将简单地修改引用的临时 r-value,当函数退出时,对象的临时 r-value 副本将被销毁。

于 2012-10-17T19:33:49.160 回答