如果涉及委托,C++ 中的 RVO 和查询结果作为对象或更好地通过引用传递

RVO in c++ and Query result as object or better pass by reference, if delegation is involved

我必须决定 return 使用对象查询的结果或通过引用传递给它们。查询将至少被委托一次。如果我 return 一个对象并进一步委托它,是否有编译器 RVO。这是一个例子:

struct foo {int a, b, c, d;}

struct b {
   Foo foo() {Foo foo; /*calculate_with_foo;*/ return foo;}
   void foo1(Foo& foo) { /*calculate_with_foo;*/ } 
}

struct delegator {
   Foo foo() {return b.foo();}
   void foo1(Foo& foo)  {b.foo1(foo);}
   b b;
}

// Performes this slower or is here RVO at work?
delegator d;
foo result = d.foo()
// pass by reference, faster?
foo resultr;
d.foo1(resultr);

复制省略号 can be chained。所以是的,RVO 可以应用于 delegator::foo,NRVO 可以应用于 b::foo,并且可以链接这些优化,这样就不需要进行复制。

此外,在这种情况下,由于所有函数都很简单且可内联,优化器甚至可以为两个调用生成相同的输出。

总的来说,两者都很快。具体的,你应该衡量一下。

按值返回的优点是使用起来更简单,因为不需要单独的行来分配变量。此外,它允许您不关心返回的类型而只使用 auto - 不过您是否想要是个人喜好。

在不适用于您的代码的更一般情况下,按值返回允许类型不可默认构造。避免默认构造无论如何都会被修改的对象可以节省一些开销。