I have to decide to return the result of a query with an object or pass into them by reference. The query will be at least one time delegated. Is there compiler RVO if I return an object and delegate it further. Here is an example:
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);
Copy elisions can be chained. So yes, RVO can be applied to delegator::foo
and NRVO can be applied to b::foo
and those optimizations can be chained so that no copies need to be done.
Also, in this case, since all functions are simple and inlinable, the optimizer could even produce identical output for both calls.
In general, both are fast. In specific, you should measure.
The advantage of returning by value is that it's simpler to use because there is no need for separate line to allocate the variable. Also, it allows you to not care about the returned type and just use auto
- whether you want to is personal preference, though.
In a more general case, which does not apply to your code, returning by value allows the type to be non-default-constructible. Avoiding default construction of an object that's going to be modified anyway can save some overhead.