0

我关心的两种复制省略形式非常有限。它只允许在 return 语句中和使用临时变量初始化变量时。所以这些不涉及复制省略:

// Not initialization
Noisy b;
b = Noisy{};
// Not temporary
Noisy c = a;

这是什么原因?这是技术限制..还是..?

4

2 回答 2

4

优化的工作原理是完全消除一个对象,使用最终将被复制到其位置的“目标”对象的存储。然后,当复制应该发生时,目标对象已经具有正确的值,因此不需要进一步的操作。

如果目标对象已经存在,这将不起作用,因为无法在其位置创建“新”对象;或者如果在复制后需要存在被省略的对象,就像在第二个示例中那样。

于 2015-03-09T11:59:46.690 回答
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.

如果你真的想要两者xy引用同一个对象,那么显然你有参考:

Foo x;
Foo& y = x;
于 2015-03-09T12:02:36.947 回答