复制省略和简单的可复制类型
从标准的6.7.7(临时对象)中可以看到:
当将类类型X的对象传递到函数或从函数返回时,如果X至少有一个合格的复制或移动构造函数([特殊]),每个这样的构造函数都是平凡的,并且X的析构函数要么是平凡的,要么是删除的,则允许实现创建一个临时对象来保存函数参数或结果对象。临时对象分别从函数实参或返回值构造,函数的参数或返回对象被初始化,就像使用符合条件的普通构造函数复制临时对象一样(即使该构造函数不可访问或不会通过重载解析选择以执行对象的复制或移动)。 [注4:此自由度允许将类类型的对象传递给寄存器中的函数或从寄存器中的函数返回。-结束语]
这是否意味着对于简单的可复制类型,复制省略不是强制性的?我在这里的理解是,如果我们声明一个像~Object() {}
这样的析构函数,而不是不声明任何东西(因此析构函数将由编译器生成)或默认的析构函数,对象将变得不可构造,因此,必须执行复制省略(在我们尊重发生复制省略的众所周知条件的情况下)。
解决方案
原则上是这样的,但您引用的部分的目标不是免除POD类型的复制省略,而是绕过ABI对如何在函数调用中传递对象的限制。它允许POD对象通过寄存器传递。鉴于C++抽象机器对物理机器及其寄存器和调用约定一无所知,这是该标准所能做的最好的事情。有保证的副本删除是整个标准中几个更改的结果,其中包括延迟的原值实体化。具体请参考原方案p0135r1。这是否意味着对简单可复制的类型不强制执行复制省略?
通过这些更改,可以(也需要)在不涉及临时对象的情况下初始化对象([dcl.init.general]/15.6.1):
-否则,如果目标类型为(可能 简历合格)类别类型:
- 如果初始值设定项表达式是pr值,并且源类型的cv非限定版本与 类,则初始值设定项表达式用于 初始化目标对象。
相关文章