Example:
Foo make_foo(int a1, int a2){
Foo f(a1,a2);
return f;
}
Having seen such functions several times, is it just a matter of coding style / preference or is there more to it than meets the eye? Specifically this answer got me thinking with the make_unique
implementation and the claim it is exception safe - is that related to the splitting of creation and return? Or am I reading too much into this? Why not simply write
Foo make_foo(int a1, int a2){
return Foo(a1,a2);
}
Note that the answer to which you refer actually has something different:
std::unique_ptr<T> ret (new T(std::forward<Args>(args)...));
In this line of code, explicit dynamic allocation is performed. Best practices dictate that whenever you perform explicit dynamic allocation, you should immediately assign the result to a named smart pointer. For more details, consult the Boost shared_ptr
best practices documentation or Herb Sutter's GotW article, "Exception-Safe Function Calls."
It isn't always dangerous to have a new
expression as a subexpression of a larger expression, but it's a rule that is easy to forget, so it's best to always follow the best practices guideline and assign a new dynamically allocated object to a named smart pointer.
That said, there is at least one advantage to the pattern of creating a named object and then returning it: it can be a bit easier to "watch" the object in the debugger when stepping through code quickly.
One possible disadvantage is that it is potentially more difficult for a compiler to perform Return Value Optimization (RVO) with a named object. Named Return Value Optimization (NRVO) is not always as straightforward as RVO with an unnamed temporary. I'd hazard to guess that modern compilers wouldn't have a problem either way, but I am not an expert on C++ compiler optimizations.