title: Avoiding extra move in make_unique/make_shared/emplace/etc for structures that use aggregate initialization
body: <p><code>std::make_unique()</code> (and similar functions) have a little <a href="http://coliru.stacked-crooked.com/a/7d4063069bcca194" rel="nofollow noreferrer">problem</a>:</p>
  <pre><code>#include &lt;cstdio&gt;
  #include &lt;memory&gt;
  
  using namespace std;
  
  struct S
  {
      S()         { printf(&quot;ctor\n&quot;); }
      ~S()        { printf(&quot;dtor\n&quot;); }
      S(S const&amp;) { printf(&quot;cctor\n&quot;); }
      S(S&amp;&amp;)      { printf(&quot;mctor\n&quot;); }
  };
  
  S foo() { return S(); }
  
  int main()
  {
      {
          printf(&quot;--------------- case 1 ---------------\n&quot;);
          unique_ptr&lt;S&gt; s1 = make_unique&lt;S&gt;( foo() );
      }
  
      {
          printf(&quot;--------------- case 2 ---------------\n&quot;);
          unique_ptr&lt;S&gt; s2 { new S( foo() ) };
      }
  }
  </code></pre>
  <p>Output:</p>
  <pre><code>--------------- case 1 ---------------
  ctor
  mctor
  dtor
  dtor
  --------------- case 2 ---------------
  ctor
  dtor
  </code></pre>
  <p>As you see we have an extra move that can be avoided. <a href="http://coliru.stacked-crooked.com/a/242db546828a40f2" rel="nofollow noreferrer">Same</a> problem exists with <code>emplace()</code> in optional/variant/etc -- if object gets returned by other function, you have to move it.</p>
  <p>This can be <a href="http://coliru.stacked-crooked.com/a/fb9f008ff76a53b7" rel="nofollow noreferrer">addressed</a> with a trick:</p>
  <pre><code>#include &lt;cstdio&gt;
  #include &lt;optional&gt;
  
  using namespace std;
  
  struct S
  {
      S()         { printf(&quot;ctor\n&quot;); }
      ~S()        { printf(&quot;dtor\n&quot;); }
      S(S const&amp;) { printf(&quot;cctor\n&quot;); }
      S(S&amp;&amp;)      { printf(&quot;mctor\n&quot;); }
  
      template&lt;class F, enable_if_t&lt;is_same_v&lt;invoke_result_t&lt;F&gt;, S&gt;&gt;...&gt;
      S(F&amp;&amp; f) : S(forward&lt;F&gt;(f)()) {}
  };
  
  S foo() { return S(); }
  
  int main()
  {
      optional&lt;S&gt; s;
      s.emplace( []{ return foo(); } );
  }
  </code></pre>
  <p>This avoids unnecessary move (enable_if hides constructor unless <code>f()</code> returns an instance of S). You effectively end up constructing your values inside of <code>std::variant</code>/<code>std::optional</code>/etc via a call to your constructing function.</p>
  <p>This fix has a little problem -- adding a constructor breaks aggregate initialization. See <a href="http://coliru.stacked-crooked.com/a/e941d4788396acdc" rel="nofollow noreferrer">example</a>. I.e. if given structure had no constructor and you add one -- you can no longer initialize it like this:</p>
  <pre><code>struct D
  {
      float m;
      S s;
  
      // adding new constructor here will break existing bar() functions
  };
  
  D bar() { /*...lots of code with multiple return statements...*/ return {2.0, foo()}; }
  </code></pre>
  <p>Question: Is there a way around this problem? Something that doesn't introduce new constructors...</p>
  <p>I'd like to be able to efficiently put my structures into optional/variant/shared_ptr-block/etc without breaking (rather non-trivial) code that creates them.</p>
  <hr />
  <p><strong>Edit</strong>: All MSVC versions can't handle exceptions escaping from Barry's <code>factory</code>. See details <a href="https://stackoverflow.com/questions/62841404/looks-like-is-nothrow-constructible-v-is-broken-in-msvc-am-i-wrong">here</a>.</p>