We all know that
Foo returnAFoo()
{
return Foo();
}
will be compiled with return value optimisation so a value copy will not be taken even if the copy constructor of Foo
has side effects. But will
Foo returnAFoo()
{
Foo f = Foo();
return f;
}
too? The second construct can be helpful when debugging. But am I throwing away an important optimisation in doing so? Perhaps I need to write an explicit move constructor?
No. Copy elision can still be applied here. In this specific case, it is called NRVO (named return value optimisation). You don't need a move constructor for copy elision to be performed; copy elision has been in the standard since C++98/03, when we only had copy constructors.
To maximise your chance of copy elision being used, you should make sure that either: all code paths return the same object (NRVO) or all code paths return a temporary object (RVO).
If you mix and match NRVO and RVO inside the same function it becomes hard to apply the optimisation.
Sample code demonstrating NRVO.