title: Why Structured Bindings disable both RVO and move on return statement?
body: <p>Suppose we have a class named <code>AAA</code> that supports both <strong>copy/move</strong>:</p>
  
  <pre><code>class AAA
  {
  public:
      AAA() = default;
      ~AAA() = default;
  
      AAA(const AAA&amp; rhs)
      {
         std::cout &lt;&lt; "Copy constructor" &lt;&lt; std::endl;
      }
  
      AAA(AAA&amp;&amp; rhs)
      {
         std::cout &lt;&lt; "Move constructor" &lt;&lt; std::endl;
      }
  };
  </code></pre>
  
  <p>In the following code, <code>get_val</code> returns <code>second</code>:</p>
  
  <pre><code>AAA get_val()
  {
      auto [ first, second ]  = std::make_tuple(AAA{}, AAA{});
  
      std::cout &lt;&lt; "Returning - " &lt;&lt; std::endl;
      return second;
  }
  
  auto obj = get_val();
  std::cout &lt;&lt; "Returned - " &lt;&lt; std::endl;
  </code></pre>
  
  <p>Now <code>second</code> is copied, printing the following output:</p>
  
  <pre><code>...
  Returning - 
  Copy constructor 
  Returned -
  </code></pre>
  
  <p>This is unfortunate, because my expectation of the result is either there's no call to copy constructor, or at least it's <em>implicitly</em> moved.</p>
  
  <p>To avoid copying, I'll have to explicitly apply <code>std::move</code> on it.</p>
  
  <pre><code>return std::move(second);
  </code></pre>
  
  <p>Then I'd receive the result of:</p>
  
  <pre><code>...
  Returning - 
  Move constructor 
  Returned - 
  </code></pre>
  
  <p>I assume that the reason <strong>RVO</strong> is not performed is that probably the compilers would see <code>second</code> as a reference instead, while <code>get_val</code> returns prvalue.</p>
  
  <p>However why can implicit move NOT be expected either? 
  Using explicit <code>std::move</code> on the return statement does not look intuitive in this particular case, because <a href="https://stackoverflow.com/questions/19267408/why-does-stdmove-prevent-rvo">you generally don't want to make RVO, which is in most cases a better optimization than move, accidentally gone away</a>.</p>
  
  <p>Tested by both compilers gcc and clang with <code>-O3</code>. </p>
  
  <p><a href="https://wandbox.org/permlink/5RPFJstLvYo62ThB" rel="noreferrer">Live Demo</a></p>