参考讨论here
$ 3.7.1 / 2 - “如果静态存储持续时间的对象具有初始化或具有副作用的析构函数,即使它似乎未被使用也不应被删除,除非可以消除类对象或其副本如12.8中所述。“
$ 12.8 / 15-“当满足某些条件时,允许实现省略类对象的复制结构,即使该对象的复制构造函数和/或析构函数有副作用。”
在上述情况下,是一个案例的具体示例,即使是易失性读/写也可能被优化掉(例如,如果复制构造函数对volatile变量有读/写)。
所以问题是“即使复制构造函数具有对volatile变量的读/写,也可以省略复制构造函数吗?”
答案 0 :(得分:0)
仅当命名对象是非易失性时才允许NRVO [它在您引用的同一部分中的权利,即第一个子弹],否则我不明白为什么不这样做。毕竟,如果你创建的对象是易变的,你仍然在写它,你只是不是通过复制构造函数这样做。并且它没有限定允许忽略哪些副作用,所以很明显,如果易失性读/写在复制构造函数本身内,编译器就不必关心。
答案 1 :(得分:0)
有时。有趣的是你应该问,因为我误解了volatile
(约翰尼斯叫出来的)让我查出了这样的琐事。
§12.8/ 15:
在函数的return语句中 用类返回类型的时候 表达式是一个名称 用非易失性自动对象 同样的cv-unqualified类型 函数返回类型,副本 操作可以省略 构造自动对象 直接进入函数的返回 值
因此,可以通过删除构造函数来消除volatile
访问,但是如果整个对象是易变的则不行。
此外,如果函数按值而不是普通volatile foo
返回foo
,那么可以有所作为,因为构造了volatile暂时不能被省略!
foo factory_a(); // return class by value
const foo factory_b(); // also return by value: rather pointless
volatile foo factory_c(); // implies no elision
请注意,返回的临时的cv限定也会影响临时的访问语义,例如factory_b().non_const_method()
是非法的。所以这比愚蠢的更加神秘。