我知道某个对象只是作为临时对象创建的(它是库中的私有成员对象)。有时,通过将成员函数链接在一起(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());
答案 0 :(得分:3)
使用移动语义,您不希望(或需要)从函数返回r值引用... r值引用是指" capture"未命名的值或内存地址。当你从调用者的角度返回一个实际上是l值的对象的r值引用时,语义都是错误的,并且当其他人使用你的对象时你创造了不必要的惊喜的机会&# 39;方法。
换句话说,最好将代码定位如下:
Foo foo(std::move(TempObj().Member()));
并让TempObj::Member
只返回一个l值引用。这使得移动变得明确,并且使用对象方法的人不会涉及任何惊喜。
最后,不,它在功能上或语义上与上一个例子不同。在那里,您实际上正在创建对象的临时副本,并且该副本将是一个r值对象(即,此场景中的一个未命名对象)...因为具有r值引用的假设是对象是一个unamed值或对象,因此它可以通过传递给它的函数进行无害修改,该函数采用r值引用参数。另一方面,如果您已将对象的副本传递给函数,则该函数无法修改原始函数。它只会修改引用的临时r值,当函数退出时,对象的临时r值副本将被销毁。