https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87855
Bug ID: 87855 Summary: std::optional<T> only copy-constructible if T is trivially copy-constructible Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: fiesh at zefix dot tv Target Milestone: --- For a type T that is non-trivially copy constructible, std::optional<T> is not copy constructible. However, only clang catches this behavior. I think clang is right in doing so because a union's copy constructor is deleted if at least one of its members has a non-trivial one. (If this is true, is it a separate gcc bug that it does not delete the union's constructor?) The following program exemplifies this: #include <optional> struct S { S() = default; S(S const &) {} }; void f() { using T = std::optional<S>; const T t0; const auto t1 = t0; (void) t1; } clang reports: /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:268:9: error: call to implicitly-deleted copy constructor of 'std::_Optional_payload<S, true, true, true>' : _Optional_payload(__engaged ? ^ ~~~~~~~~~~~ /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:733:4: note: in instantiation of member function 'std::_Optional_payload<S, true, true, true>::_Optional_payload' requested here : _M_payload(__other._M_payload._M_engaged, ^ /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:985:11: note: in instantiation of member function 'std::_Optional_base<S, false, false>: :_Optional_base' requested here class optional ^ /tmp/t.cpp:15:18: note: in implicit copy constructor for 'std::optional<S>' first required here const auto t1 = t0; ^ /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include/g++-v8/optional:288:24: note: copy constructor of '_Optional_payload<S, true, true, true>' is implicitly deleted because variant field '_M_payload' has a non-trivial copy constructor _Stored_type _M_payload;