Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the behaviour of compiler generated move constructor?
    text
    copied!<p>Does <code>std::is_move_constructible&lt;T&gt;::value == true</code> imply that <code>T</code> has a usable move constructor? If so, what is the default behaviour of it?</p> <p>Consider the following case:</p> <pre><code>struct foo { int* ptr; }; int main() { { std::cout &lt;&lt; std::is_move_constructible&lt;foo&gt;::value &lt;&lt; '\n'; foo f; f.ptr = (int*)12; foo f2(std::move(f)); std::cout &lt;&lt; f.ptr &lt;&lt; ' ' &lt;&lt; f2.ptr &lt;&lt; '\n'; } return 0; } </code></pre> <p>and the output is:</p> <pre><code>1 0000000C 0000000C </code></pre> <p>I thought that <code>f.ptr</code> should be <code>nullptr</code>. So in this case, </p> <ol> <li>Is <code>f2</code> move constructed ?</li> <li>If so, shouldn't the rvalue be invalidated?</li> <li>How can I know if instances of a class can be properly move-constructed (invalidate the old one)?</li> </ol> <p>(I'm using VS11.)</p> <h2>Update</h2> <p>The default behaviour of move constructor is same as a copy constructor, is it correct? If it's true,</p> <ol> <li>We always expect a move ctor to steal the resources of the moved-from object, while the default one does not behave as expected, so what's the point of having a default move ctor? </li> <li>How can I know if a class has a custom move constructor (which can be guaranteed to behave properly)?</li> </ol> <p>It seems that <code>foo f2(std::move(f));</code> calls the copy ctor when I declared one, see:</p> <pre><code>struct foo { int* ptr; foo() {} foo(const foo&amp; other) { std::cout &lt;&lt; "copy constructed\n"; } }; int main() { { std::cout &lt;&lt; std::is_move_constructible&lt;foo&gt;::value &lt;&lt; '\n'; foo f; foo f2(std::move(f)); } system("pause"); return 0; } </code></pre> <p>Now the output is:</p> <pre><code>1 copy constructed </code></pre> <p>If <code>foo</code> has a move constructor, then wouldn't <code>foo f2(std::move(f))</code> call it?</p> <p>So now my questions is: How to know if a class has a move ctor, and if it has one, how can I explicitly call it?</p> <h2>What I'm trying to do is…</h2> <pre><code>template&lt;typename T, bool has_move_ctor&gt; struct MoveAux; template&lt;typename T&gt; struct MoveAux&lt;T, true&gt; { static void doMove(T* dest, T* src) { new(dest) T(std::move(*src)); //move ctor } }; template&lt;typename T&gt; struct MoveAux&lt;T, false&gt; { static void doMove(T* dest, T* src) { new(dest) T(*src); //copy ctor src-&gt;~T(); } }; template&lt;typename T&gt; inline doMove(T* dest, T* src) { MoveAux&lt;T,/*a trait*/&gt;::doMove(dest, src); } </code></pre> <p>So I thought <code>std::is_move_constructible&lt;T&gt;::value</code> can be passed to the template, while now I see that this trait only cares if <code>T t(T())</code> is a valid expression, it may call <code>T::T(const T&amp;)</code>. Now assume that <code>T</code> is a custom class, then I want the above templates to behave like:</p> <ol> <li>If I don't declare a move ctor, I want that template method calls the <code>MoveAux&lt;T,false&gt;::doMove</code>.</li> <li>If I declared one, I need it calls to <code>MoveAux&lt;T,true&gt;::doMove</code>.</li> </ol> <p>Is it possible to make this work?</p>
 

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