RVO是否适用于对象成员?

Nub*_*ase 14 c++ visual-c++ return-value-optimization c++11 c++14

考虑以下:

struct A { /* ... */ };

A foo() {
  auto p = std::make_pair(A{}, 2);
  // ... do something
  return p.first;
}

auto a = foo();
Run Code Online (Sandbox Code Playgroud)

p.first被复制,移动还是RVO-ed?

atk*_*ins 10

我在Visual Studio 2010中找到并且在gcc-5.1中没有应用RVO (例如参见http://coliru.stacked-crooked.com/a/17666dd9e532da76).

该标准的相关部分是12.8.31.1 [class.copy].它声明允许复制省略(我强调):

在具有类返回类型的函数的return语句中,当表达式是非易失性自动对象名称时(除了函数参数或由处理程序的异常声明引入的变量([except.handle]) ))具有与函数返回类型相同的类型(忽略cv-qualification),通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作

由于p.first不是对象的名称,因此禁止使用RVO.

  • p.first绝对不是对象的名称.:-) (2认同)
  • @rozina:实际上它起到了指示物的名称.这是引用的全部目的,与指针不同._But_我不确定根据标准术语有多少,而不是从使用中获得的英语术语. (2认同)
  • @LightnessRacesinOrbit gcc-5.1考虑返回一个引用*甚至是一个简单的本地对象*就足以关闭RVO(http://coliru.stacked-crooked.com/a/84e5744d0a68f6dd).有趣! (2认同)
  • 在8.3.2.1 [dcl.ref]中,有这个"注意":*引用可以被认为是对象的名称.*我们是否认为"可以想到,但事实上并非如此"? ! (2认同)

And*_*tur 10

只是为了增加一点燃料,如果RVO起作用,它将如何发挥作用?调用者A在内存中放置了一个实例,然后调用foo赋值给它(更好的是,让我们假设它A是更大结构的一部分,让我们假设它是正确对齐的,这样结构的下一个成员就是紧接着那个例子之后A).假设RVO均发挥,first部分p位于其中呼叫者想要它,但哪里的intsecond得到安置?它必须在实例之后A才能保持pair正常运行,但是在源位置,在该实例之后还有一些其他成员A.

我希望RVO不会在这个地方发生,因为你只返回一个更大的对象的一部分.可能会发生first一个必须留在可破坏状态的举动.