我无法理解RVO (和NRVO)的定义,因为就像这个存在多个问题,在我看来,这些问题假设RVO忽略了一个复制构造函数。现在根据12.8.15
在这种情况下,实现将省略复制操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在如果不进行优化就会销毁这两个对象的后期。
它看起来不是复制构造函数调用被省略了,而是复制本身--只是对象首先是在“复制”位置构造的,所以根本没有“原始”对象,也没有复制。因此,即使一个类有一个private副本构造函数,它也可以在RVO启动时从函数返回,因为没有副本。
我做得对吗?复制本身是省略了还是复制构造函数调用省略了?当对象类具有私有副本构造函数时,是否应该允许从函数返回对象?
发布于 2012-04-24 06:35:52
根据官方说法,RVO/NRVO并不影响程序的格式是否良好。该标准显式地允许省略来自复制构造函数的任何副作用,但是仍然需要对复制构造函数进行访问检查。
但是,大多数编译器不会对省略的复制构造函数进行访问检查,除非您要求尽可能严格地强制执行规则。我不完全确定,但我似乎还记得曾经使用过一些跳过访问检查的方法,即使您确实要求严格遵守(但我不太清楚)。
编辑(以纠正我认为在其他一些答案中表达的误解):
标准某一节中的段落按顺序阅读。第一段中适用于某一情况的要求总是适用的。在这种情况下,可以在第15段中略去副作用,但在第14段之前,我们看到:
如果隐式使用对象的复制构造函数或复制赋值操作符,并且无法访问特殊的成员函数,则程序的格式是错误的(第11条)。
因此,如果第14段中指定的访问检查已经通过,我们只会到第15段(可以省略复制)。
发布于 2012-04-24 06:31:59
如果优化生效,将省略复制,但仍需要编译器检查副本构造函数是否可访问。否则,如果编译器(或其他编译器)决定不进行优化,代码将无效。
发布于 2012-04-24 06:35:01
是省略了复制本身,还是忽略了复制构造函数调用?
复制操作本身被取消。如果你看一下全文,它就清楚地提到了这一点:
C++ 03 12.8复制类对象
第15段
当满足某些条件时,即使对象的复制构造函数和/或析构函数有副作用,也允许实现省略类对象的复制构造。在这种情况下,默示将省略复制操作的源和目标视为引用同一对象的两种不同方式,而该对象的销毁发生在如果不进行优化就会销毁两个对象的晚些时候。111)在下列情况下允许这种复制操作的省略(可以合并使用以消除多个副本): -在具有类返回类型的函数中的返回语句中,当表达式是具有与函数返回类型相同的cv-非限定类型的非易失性自动对象的名称时,可以通过将自动对象直接构造到函数的返回值来省略操作。 -当没有绑定到引用(12.2)的临时类对象被复制到具有相同cv-非限定类型的类对象时,可以通过将临时对象直接构造到省略副本的目标中来省略操作……
当对象类具有私有副本构造函数?时,应该允许从函数返回对象。
RVO和NRVO是编译器的优化,编译器允许使用,但不能保证,如果特定的哑编译器不能提供这些优化怎么办?
如果没有可访问的复制构造函数,代码将中断在所有这类编译器上,这是不需要的。假定复制构造函数应该是可访问的。
https://stackoverflow.com/questions/10292646
复制相似问题