何时调用移动 ctor?
Posted
技术标签:
【中文标题】何时调用移动 ctor?【英文标题】:When will the move ctor be invoked? 【发布时间】:2010-08-05 09:18:21 【问题描述】:给定类:
class C
public:
C()
cout << "Dflt ctor.";
C(C& obj)
cout << "Copy ctor.";
C(C&& obj)
cout << "Move ctor.";
C& operator=(C& obj)
cout << "operator=";
return obj;
C& operator=(C&& obj)
cout << "Move operator=";
return obj;
;
然后在 main:
int main(int argc, char* argv[])
C c;
C d = c;
C e;
e = c;
return 0;
正如您将从输出中看到的那样,调用了“常规”版本的复制 ctor 和 operator=
,但没有调用具有右值参数的那些。所以想问一下move ctor和operator=(C&&)
在什么情况下会被调用?
【问题讨论】:
【参考方案1】:当右侧是临时的,或者使用static_cast<C&&>
或std::move
显式转换为C&&
时,将调用移动构造函数。
C c;
C d(std::move(c)); // move constructor
C e(static_cast<C&&>(c)); // move constructor
C f;
f=std::move(c); // move assignment
f=static_cast<C&&>(c); // move assignment
C g((C())); // move construct from temporary (extra parens needed for parsing)
f=C(); // move assign from temporary
【讨论】:
【参考方案2】:IIRC,你必须使用C d = std::move(c)
才能使用移动构造函数。
一个未经测试的例子,但可以更好地解释移动构造函数的使用:
C&& foo() C c; return std::move(c);
【讨论】:
【参考方案3】:您的所有变量都是左值,因此不能隐式移动,因为您以后可能需要访问它们。此外,复制构造函数和赋值运算符采用 const 引用。
右值引用适用于右值,即临时对象。为了查看使用的移动构造函数,首先,您必须实际创建一个临时对象。此外,不要忘记 RVO 仍然适用,并且很可能会确定您的任何或所有 std::cout 调用。
您可以使用 std::move(lvalue) 从左值创建右值。
【讨论】:
【参考方案4】:std::swap(c,e); // c and e variables declared in your _tmain()
将调用移动构造函数。
【讨论】:
【参考方案5】:如果你有一个静态类,它返回在本地堆栈上创建的 C&&,则更实际的使用移动运算符的示例如下:
static C&& CreateC()
C c();
//do something with your object
return c;
然后你像这样调用它:
C x = CreateC(); // move operator is invoked here
【讨论】:
投反对票时请留言以上是关于何时调用移动 ctor?的主要内容,如果未能解决你的问题,请参考以下文章
自动生成默认/复制/移动 ctor 和复制/移动赋值运算符的条件?
将 std::string ctor 参数传递给具有移动语义的 pimpl 中的 impl