title: Why does clang, using libstdc++, delete the explicitly defaulted constructor on a type containing std::optional?
body: <p>Consider the following structure with an <code>std::optional</code> containing a type that definitely has a &quot;normal&quot; default constructor.</p>
  <pre><code>#include &lt;optional&gt;
  #include &lt;string&gt;
  
  struct Foo
  {
      Foo() = default;
      const std::optional&lt;std::string&gt; m_value;
  };
  
  bool function()
  {
      Foo foo;
      return bool(foo.m_value);
  }
  </code></pre>
  <p>Compiling the following with clang 9 (using the system's default <code>libstdc++</code>, for its gcc 8) gives an unexpected warning:</p>
  <pre><code>&lt;source&gt;:6:5: warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
      Foo() = default;
      ^
  &lt;source&gt;:7:38: note: default constructor of 'Foo' is implicitly deleted because field 'm_value' of const-qualified type 'const std::optional&lt;std::string&gt;' (aka 'const optional&lt;basic_string&lt;char&gt; &gt;') would not be initialized
      const std::optional&lt;std::string&gt; m_value;
                                       ^
  </code></pre>
  <p>There's also hard error for <code>Foo foo;</code> since it uses said deleted constructor.</p>
  <ul>
  <li>Deleting the <code>Foo() = default;</code> constructor gives the same results.</li>
  <li>Replacing it with <code>Foo() {}</code> works!</li>
  <li>Removing all the constructors and initializing <code>foo</code> as <code>Foo foo{};</code> works!</li>
  <li>Explicitly initializing the member as <code>const std::optional&lt;std::string&gt; m_value{};</code> works!</li>
  <li>Removing the <code>const</code> from the member works! (but isn't the same meaning)</li>
  <li>Using clang 9 with <code>-stdlib=libc++</code> works!</li>
  <li>Using gcc 8.3 (still with <code>libstdc++</code>) works!</li>
  </ul>
  <p>I've read <a href="https://stackoverflow.com/questions/57964217">std::optional - construct empty with {} or std::nullopt?</a> which seems to indicate that the <code>libstdc++</code> implementation choice of an <code>= default</code> constructor for <code>std::optional</code> is likely to blame.  But, in that question, the concern was a matter of efficiency of one approach vs. the other.  In this case, it seems like a matter of <em>correctness</em>.</p>
  <p>(I suspect that the answer to <a href="https://stackoverflow.com/q/36342296/693212">How can std::chrono::duration::duration() be constexpr?</a> is going to be part of the story here.)</p>
  <p>I see the same behaviour on Compiler Explorer: <a href="https://gcc.godbolt.org/z/Yj1o5P" rel="noreferrer">https://gcc.godbolt.org/z/Yj1o5P</a></p>
  <p>Compare simple structures of optional and non-optional <code>std::string</code> (in the non-working configurations):</p>
  <pre><code>struct Foo { const std::optional&lt;std::string&gt; m_value; };
  auto f1() { Foo f; return f.m_value; } // Fails: call to implicitly deleted constructor.
  
  struct Bar { const std::string m_value; };
  auto f2() { Bar b; return b.m_value; } // Works.
  </code></pre>
  <p>Is this a bug in <code>libstdc++</code>?  Is it mixed intentions and assumptions between clang and <code>libstdc++</code>?</p>
  <p>Surely the intent can't be that I can have a structure with a <code>const std::string</code> but I can't have a structure with a <code>const std::optional&lt;std::string&gt;</code> unless I wrote a constructor?</p>
  <p>(In real-word cases, you'd have additional constructors, too.  Thus the motivation for an <code>= default()</code> constructor in the first place.  That, and clang-tidy.)</p>
  <p>Edit: Here's an expanded version of the example (<a href="https://gcc.godbolt.org/z/5bssGa" rel="noreferrer">Compiler Explorer</a>) showing a similar example working in &quot;pure clang&quot;, &quot;pure gcc&quot;, but failing in mixed &quot;clang+libstdc++&quot;.  This slightly bigger example is still artificial, but hints at why one might want to actually have such a defaulted constructor.</p>
  <pre><code>struct Foo
  {
      Foo() = default; // Implicitly deleted?!
      explicit Foo(std::string arg) : m_value{std::move(arg)} {}
      const auto&amp; get() const noexcept { return m_value; }
    private:    
      const std::optional&lt;std::string&gt; m_value;
  };
  
  // Maybe return an empty or a full Foo.
  auto function(bool flag, std::string x)
  {
      Foo foo1;
      Foo foo2{x};
      return flag ? foo1 : foo2;
  }
  </code></pre>