More C++ Idioms/Computational Constructor

= Computational Constructor =

Intent

 * Optimize return-by-value
 * Allow Return Value Optimization (RVO) on compilers that cannot handle Named Return Value Optimization (NRVO)

Motivation
Returning large C++ objects by value is expensive in C++. When a locally created object is returned by-value from a function, a temporary object is created on the stack. The temporaries are often very short-lived because they are either assigned to other objects or passed to other functions. Temporary objects generally go out-of-scope and hence destroyed after the statement that created them is executed completely.

Over the years compilers have evolved to apply several optimizations to avoid creation of temporaries because it is often wasteful and hampers performance. Return Value Optimization (RVO) and Named Return Value Optimization (NRVO) are two popular compiler techniques that try to optimize away the temporaries (a.k.a. copy elision). A brief explanation of RVO is in order.

Return Value Optimization

The following example demonstrates a scenario where the implementation may eliminate one or both of the copies being made, even if the copy constructor has a visible side effect (printing text). The first copy that may be eliminated is the one where  is copied into the function  's return value. The second copy that may be eliminated is the copy of the temporary object returned by  to. More on RVO is available on Wikipedia

Following pseudo-code shows how both the copies of  can be eliminated.

Named Return Value Optimization (NRVO) is a more advanced cousin of RVO and not all compilers support it. Note that function  above did not name the local object it created. Often functions are more complicated than that. They create local objects, manipulate its state, and return the updated object. Eliminating the local object in such cases requires NRVO. Consider the following somewhat contrived example to emphasize the computational part of this idiom.

In the above example, function  does a lot of computation on object   before returning it. The implementation cannot use RVO because the object has a name ("f"). NRVO is possible but its support is not universal. Computational constructor idiom is a way to achieve return value optimization even in such cases.

Solution and Sample Code
To exploit RVO, the idea behind computational constructor idiom is to put the computation in a constructor so that the compiler is more likely to perform the optimization. A new four parameter constructor has been added just to enable RVO, which is a computational constructor for class. The  function is now much more simple than before and the compiler will likely apply RVO here.

Consequences
A common criticism against the computational constructor idiom is that it leads to unnatural constructors, which is partly true for the class  shown above. If the idiom is applied judiciously, it can limit the proliferation of computational constructors in a class and yet provide better run-time performance.