title: C++ Implicit Conversion from R-Value
body: <p>I'm trying to define an implicit conversion operator that will move a wrapper type into the implicit type as such:</p>
  
  <pre><code>#include &lt;utility&gt;
  #include &lt;iostream&gt;
  
  struct SomeStruct
  {
      int a;
      int b;
      int c;
  };
  
  struct AnyStruct 
  {
      template &lt;typename T&gt;
      T&amp; Get();
  
      template &lt;typename T&gt;
      const T&amp; Get() const;
  
      template &lt;typename T&gt;
      operator T&amp; ()&amp;
      {
          std::cout &lt;&lt; "lvalue conversion\n";
          return Get&lt;T&gt;();
      }
  
      template &lt;typename T&gt;
      operator const T&amp; () const&amp;
      {
          std::cout &lt;&lt; "const lvalue conversion\n";
          return Get&lt;T&gt;();
      }
  
      template &lt;typename T&gt;
      operator T()&amp;&amp;
      {
          std::cout &lt;&lt; "rvalue conversion\n";
          return std::move(Get&lt;T&gt;());
      }
  
      SomeStruct cheat = { 0, 0, 0 };
  };
  
  template &lt;&gt;
  SomeStruct&amp; AnyStruct::Get&lt;SomeStruct&gt;()
  {
      return cheat;
  }
  
  template &lt;&gt;
  const SomeStruct&amp; AnyStruct::Get&lt;SomeStruct&gt;() const
  {
      return cheat;
  }
  
  int main()
  {
      AnyStruct s2;
      SomeStruct s4 = std::move(s2);
      static_cast&lt;void&gt;(s4);
  }
  </code></pre>
  
  <p>The first implicit conversion works and calls the right cast operator <code>operator T&amp;() &amp;</code>. I would have expected the second implicit conversion to call the right cast operator <code>operator T() &amp;&amp;</code> and move <code>s2</code> into <code>s4</code>, but it calls the cast operator <code>operator T&amp;() &amp;</code> instead and actually copy the struct.</p>
  
  <p>What am I doing wrong?</p>
  
  <p>EDIT: This whole issue looks like a problem with MSVC. This statement will copy construct: <code>SomeStruct s = std::move(a);</code> but this one will move construct: <code>SomeStruct s = std::move(a.Get&lt;SomeStruct&gt;());</code> MSVC never picks the rvalue cast operator in the first case.</p>