(我将 gcc 与 -O2
一起使用。)
这似乎是一个直接省略复制构造函数的机会,因为访问 bar
的 foo拷贝中的字段值没有副作用
;但是复制构造函数被调用了,因为我得到了输出meep meep!
。
#include <iostream>
struct foo {
foo(): a(5) { }
foo(const foo& f): a(f.a) { std::cout << "meep meep!\n"; }
int a;
};
struct bar {
foo F() const { return f; }
foo f;
};
int main()
{
bar b;
int a = b.F().a;
return 0;
}
最佳答案
它不是 12.8/15 中描述的复制 ctor 省略的两个法律案例:
返回值优化(其中从函数返回自动变量,并且通过直接在返回值中构造自动变量来省略自动变量到返回值的复制)- 不。 f
不是自动变量。
临时初始值设定项(将临时值复制到对象,而不是构造临时值并复制它,临时值直接构造到目标中)- 不 f
也不是临时值. b.F()
是临时的,但它不会被复制到任何地方,它只是访问了一个数据成员,所以当你离开 F()
时,什么都没有省略。
由于复制 ctor elision apples 和将 f
复制到 F()
的返回值这两个法律案例都不会影响程序的可观察行为,该标准禁止将其删除。如果你用一些不可观察的事件替换了打印,并检查了程序集,你可能会发现这个复制构造函数已经被优化掉了。但那是在“as-if”规则下,而不是在复制构造函数省略规则下。
关于c++ - 为什么这里没有省略复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2717361/