鉴于此应用程序:
#include <iostream>
struct X {
X(int _x) { x = _x + 1; }
X(const X& that) { x = that.x + 10; }
X& operator=(const X& that) { x = that.x + 100; return *this; }
X(X&& that) { x = that.x + 1000; }
X& operator=(X&& that) { x = that.x + 10000; return *this; }
int x;
};
int main() {
X a(1);
std::cout << "a.x=" << a.x << std::endl;
X b = 2;
std::cout << "b.x=" << b.x << std::endl;
X c = X(3);
std::cout << "c.x=" << c.x << std::endl;
X d = a;
std::cout << "d.x=" << d.x << std::endl;
}
我预计输出是:
a.x=2
b.x=1003
c.x=1004
d.x=12
然而我得到的是:
a.x=2
b.x=3
c.x=4
d.x=12
实例 http://rextester.com/IRR1416
获得我的预期输出的唯一方法是编译-fno-elide-constructors
(example http://rextester.com/QKSH83987)
我认为编译器可能不会删除一些东西,如果这样做会影响观察到的行为,但 GCC、clang 和 MSVC 似乎就是这么做的。
我是否遗漏了一些一般规则,或者它是否特定于临时对象初始化?
即使忽略副作用,复制省略也是允许发生的:
[class.copy]/31:
当满足某些条件时,允许实现省略类的复制/移动构造
目的,即使为复制/移动操作选择了构造函数和/或为对象选择了析构函数
有副作用. [...]
一个好的通用规则是不要编写依赖于复制/移动构造函数副作用的代码,因为您很容易被省略所困扰。在 C++17 中尤其如此,其中某些复制省略情况是强制性的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)