我关心的两种复制形式非常有限。它只允许在return语句中以及使用临时语句初始化变量时。因此,这些不涉及复制省略:
// Not initialization
Noisy b;
b = Noisy{};
// Not temporary
Noisy c = a;
这是什么原因?这是技术限制..还是......?
答案 0 :(得分:4)
优化的工作原理是完全消除一个对象,使用" target"最终将它复制到其位置的对象。然后,当副本发生时,目标对象已经具有正确的值,因此不需要进一步的操作。
如果目标对象已经存在,那将无法工作,因为" new"对象无法在其位置创建;或者如果复制后需要存在被删除的对象,就像在第二个例子中那样。
答案 1 :(得分:2)
当你复制的东西还活着的时候,你怎么看待复制省略?您的代码仍然有两个有效对象,但如果您要忽略复制操作,那么它们实际上是同一个对象。你能想象这会有多混乱吗?
Foo x;
Foo y = x;
// Now are `x` and `y` the same object, or not?
// Which one will have its destructor invoked?
这正是移动语义被发明的原因;您明确表示您希望x
并将其值移至y
,并使x
处于有效但未指定的状态:
Foo x;
Foo y = std::move(x);
// I've indicated, explicitly, that `x` is not much of anything any more.
// It's my responsibility now to abide by that contract.
如果你确实希望x
和y
同时引用同一个对象,那么显然你有参考资料:
Foo x;
Foo& y = x;