Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It appears it is not the move ctor, nor the templated move ctor that is causing the problem, but the presence of <code>enable_if&lt;is_convertable&lt;...</code> in the templated move ctor:</p> <p>Testing with just an object, throwing <code>auto</code> and <code>pair</code> out of the test:</p> <ul> <li><p>OK, copy/move elided:</p> <pre><code> cout &lt;&lt; "# Construct Object: auto obj = LogMe();\n"; LogMe obj = LogMe(); LogMe(LogMe&amp;&amp;) { cout &lt;&lt; __FUNCTION__ ... } </code></pre></li> </ul> <p>And, with a test like so:</p> <pre><code> cout &lt;&lt; "# Construct Object: LogMeTempl obj = LogMeTempl();\n"; LogMeTempl obj = LogMeTempl(); cout &lt;&lt; "# Construct Object: LogMeTempl obj2;\n"; LogMeTempl obj2; </code></pre> <ul> <li><p>OK, copy move also elided:</p> <pre><code>template&lt;class Other&gt; LogMeTempl(Other&amp;&amp; rhs // , typename enable_if&lt;is_convertible&lt;Other, LogMeTempl&gt;::value, void&gt;::type ** = 0 ) { cout &lt;&lt; __FUNCTION__ &lt;&lt; ...; } </code></pre></li> <li><p><strong>Fail!</strong> Move ctor invoked!</p> <pre><code>template&lt;class Other&gt; LogMeTempl(Other&amp;&amp; rhs , typename enable_if&lt;is_convertible&lt;Other, LogMeTempl&gt;::value, void&gt;::type ** = 0 ) { cout &lt;&lt; __FUNCTION__ &lt;&lt; ...; } </code></pre> <p>And note that the enable_if can be reduced to <code>enable_if&lt;true, void&gt;::type** = 0</code> - if fact <em>any</em> additional defaulted parameter will do (e.g. <code>, int defaulted_param_on_move_ctor = 0</code> and it will still <em>prevent the move elision</em>).</p> <p>This also extends to a type with a copy-ctor only that has a default argument. It won't be elided either. A quick <a href="http://ideone.com/dBXckh" rel="nofollow">cross-check with gcc</a> shows there doesn't seem to be any such problem there.</p></li> </ul> <h3>Short Answer</h3> <p>Types with defaulted arguments in their copy/move ctor <em>don't</em> have their initialization copy/move elided.</p> <p>I have added a <a href="https://connect.microsoft.com/VisualStudio/feedback/details/805051/visual-c-11-vs-2012-copy-constructor-with-defaulted-second-argument-prevents-copy-elision" rel="nofollow">bug on MS.connect</a> for this issue.</p> <p>I have also added a test-case for (N)RVO <a href="http://ideone.com/9XcO6w" rel="nofollow">to IDEone</a>. Even without the default argument, *N*RVO seems to work better in gcc than VC++.</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.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      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