Note that there are some explanatory texts on larger screens.

plurals
  1. PORVO, move operations and a dilemma
    primarykey
    data
    text
    <p>I have been learning about move constructors over the last day or so, trying to stick to a general rule of returning by value as most people seem to suggest, and have come across an interesting (to me) dilemma.</p> <p>Assume that I have an expensive to construct/copy class 'C' that has correctly defined copy constructor, assignment operator, move constructor and move assignment operator.</p> <p>First, this piece of code elides the copy constructor as I expected:</p> <pre><code>C make_c1() { return C(); } </code></pre> <p>as does this:</p> <pre><code>C make_c2() { C tmp; return tmp; } </code></pre> <p>and so does this (whether I pass in a 1 or 2):</p> <pre><code>C make_c3(int a) { return a == 1 ? make_c1() : make_c2(); } </code></pre> <p>It's when I get to this that I have an issue:</p> <pre><code>C make_c4(int a) { C tmp; return a == 1 ? make_c1() : tmp; } </code></pre> <p>Passing in a 1 triggers RVO for the result of make_c1, but passing in a 2 triggers the copy constructor on tmp.</p> <p>Amending the function to the following causes the move constructor to be triggered for tmp instead:</p> <pre><code>C make_c5(int a) { C tmp; return a == 1 ? make_c1() : std::move(tmp); } </code></pre> <p>All great and wonderful except...</p> <p>In these simple examples, RVO has been triggered pretty much as I'd hoped.</p> <p>However what if my code is slightly more complex and on some compilers doesn't evoke RVO in that last function? In that case, I'd need to wrap my call to make_c1 in std::move, which will make the code less efficient on those compilers that do evoke RVO.</p> <p>So my questions are:</p> <ol> <li>Why was the move constructor not invoked in make_c4 when I returned my local object? (It's about to be destroyed after all).</li> <li>In the function make_c5, should I return the results of make_c1 by value or by moving it? (To avoid different versions of the code for differing compilers/platforms).</li> <li>Is there a better way to code the final function so that it does the right thing for a reasonable compiler implementation?</li> </ol> <p>The compiler I have been playing with is GCC 4.5.3 on Cygwin.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload