Say we have a class:
class Foo {
public:
Foo() = default;
Foo(const Foo&) = default;
Foo(Foo&&) = default;
// other functions...
private:
// a bunch of data members...
};
Would a C++17/C++20 compiler optimize the following return statement?
Foo CreateFoo() {
Foo foo;
// Do more things with foo ...
return foo; // Is copy elision used here? If not, would it be optimized as return std::move(foo)?
}
This behavior has not changed since C++11. A named object may be elided, provided it meets certain requirements, but it is not required.
What is guarnateed is that the object will first be treated as an rvalue for the purposes of overload resolution and if that fails then in fails back to lvalue overload resoltution. In this case that means at worst foo
will be moved out of the function if the elision, Named Return Value Optimization (NRVO), does not happen.