title: What is the best way to return multiple large objects in C++?
body: <p>I want to return a tuple containing types like <code>std::vector</code> or <code>std::unordered_map</code> etc. where the objects may be large enough that I care about not copying. I wasn't sure how copy elision / return value optimization will work when the returned objects are wrapped in a tuple. To this end I wrote some test code below and am confused by parts of its output:</p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;tuple&gt;
  #include &lt;iostream&gt;
  
  struct A {
      A() {}
  
      A(const A&amp; a) {
          std::cout &lt;&lt; &quot;copy constructor\n&quot;;
      }
  
      A(A&amp;&amp; a) noexcept {
          std::cout &lt;&lt; &quot;move constructor\n&quot;;
      }
  
      ~A() {
          std::cout &lt;&lt; &quot;destructor\n&quot;;
      }
  };
  
  struct B {
  
  };
  
  std::tuple&lt;A, B&gt; foo() {
  
      A a;
      B b;
      return { a, b };
  }
  
  std::tuple&lt;A, B&gt; bar() {
      A a;
      B b;
      return { std::move(a), std::move(b) };
  }
  
  std::tuple&lt;A, B&gt; quux() {
      A a;
      B b;
      return std::move(std::tuple&lt;A, B&gt;{ std::move(a), std::move(b) });
  }
  
  std::tuple&lt;A, B&gt; mumble() {
      A a;
      B b;
      return std::move(std::tuple&lt;A, B&gt;{ a, b });
  }
  
  int main()
  {  
      std::cout &lt;&lt; &quot;calling foo...\n\n&quot;;
      auto [a1, b1] = foo();
      std::cout &lt;&lt; &quot;\n&quot;;
  
      std::cout &lt;&lt; &quot;calling bar...\n\n&quot;;
      auto [a2, b2] = bar();
      std::cout &lt;&lt; &quot;\n&quot;;
  
      std::cout &lt;&lt; &quot;calling quux...\n\n&quot;;
      auto [a3, b3] = quux();
      std::cout &lt;&lt; &quot;\n&quot;;
  
      std::cout &lt;&lt; &quot;calling mumble...\n\n&quot;;
      auto [a4, b4] = mumble();
      std::cout &lt;&lt; &quot;\n&quot;;
  
      std::cout &lt;&lt; &quot;cleaning up main()\n&quot;;
  
      return 0;
  }
  </code></pre>
  <p>when I run the above (on VS2019) I get the following output:</p>
  <pre><code>calling foo...
  copy constructor
  destructor
  
  calling bar...
  move constructor
  destructor
  
  calling quux...
  move constructor
  move constructor
  destructor
  destructor
  
  calling mumble...
  copy constructor
  move constructor
  destructor
  destructor
  
  cleaning up main()
  destructor
  destructor
  destructor
  destructor
  </code></pre>
  <p>So from the above is looks like <code>bar()</code> is best which is <code>return { std::move(a), std::move(b) }</code>. My main question is why <code>foo()</code> ends up copying? RVO should elide the tuple from being copied but shouldn't the compiler be smart enough to not copy the A struct? The tuple constructor could be a move constructor there since it is firing in an expression that is being returned from a function i.e. because struct <code>a</code> is about to not exist.</p>
  <p>I also don't really understand what is going on with <code>quux()</code>. I didnt think that additional <code>std::move()</code> call was necessary but I don't understand why it ends up <em>causing</em> an additional move to actually occur i.e. I'd expect it to have the same output as <code>bar()</code>.</p>