我关心的两种复制省略形式非常有限。它只允许在 return 语句中和使用临时变量初始化变量时。所以这些不涉及复制省略:
// Not initialization
Noisy b;
b = Noisy{};
// Not temporary
Noisy c = a;
这是什么原因?这是技术限制..还是..?
我关心的两种复制省略形式非常有限。它只允许在 return 语句中和使用临时变量初始化变量时。所以这些不涉及复制省略:
// Not initialization
Noisy b;
b = Noisy{};
// Not temporary
Noisy c = a;
这是什么原因?这是技术限制..还是..?
优化的工作原理是完全消除一个对象,使用最终将被复制到其位置的“目标”对象的存储。然后,当复制应该发生时,目标对象已经具有正确的值,因此不需要进一步的操作。
如果目标对象已经存在,这将不起作用,因为无法在其位置创建“新”对象;或者如果在复制后需要存在被省略的对象,就像在第二个示例中那样。
当您要复制的东西要保持活力时,您如何期望复制省略工作?您的代码仍然有两个有效对象,但如果您要省略复制操作,那么它们实际上将是同一个对象。你能想象这会有多混乱吗?
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;