为什么复制构造函数不在这里?

Jes*_*der 6 c++ optimization constructor

(我正在使用gcc -O2.)

这似乎是一个简单的机会来消除复制构造函数,因为访问a 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;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 11

它不是12.8/15中描述的复制文件的两个法律案例:

返回值优化(从函数返回自动变量,并通过直接在返回值中构造自动来省略将该自动复制到返回值) - nope.f不是自动变量.

临时初始化器(临时复制到一个对象,而不是构造临时和复制它,临时值直接构造到目标) - nope f也不是临时的.b.F()是一个临时的,但它不会被复制到任何地方,只是有一个数据成员被访问,所以当你离开F()那里没有什么可以消除.

由于没有任何合法案件的复制,以及复制f到返回值都会F()影响程序的可观察行为,因此该标准禁止其被删除.如果您使用一些不可观察的活动替换了打印,并检查了程序集,您可能会看到此复制构造函数已经过优化.但这将属于"as-if"规则,而不是复制构造函数elision规则.