https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70472

--- Comment #3 from Askar Safin <safinaskar at mail dot ru> ---
(In reply to Jonathan Wakely from comment #2)
> It's not required, and it would be impossible to require it in general. The
> problem is that std::vector does have a copy constructor, so the trait value
> is true, but instantiating that constructor produces an error when the
> value_type is not copyable.
std::is_copy_constructible<std::experimental::optional<...>> is correct. Look
at the implementation. There are _Enable_special_members and _Enable_copy_move
in <bits/enable_special_members.h>. Then there is _Optional_base in
<experimental/optional>. And then there is

template<typename _Tp>
    class optional
    : private _Optional_base<_Tp>,
      private _Enable_copy_move<
        // Copy constructor.
        is_copy_constructible<_Tp>::value,
        ...
      >

in <experimental/optional>. Also, link I post ( http://paste.debian.net/422907/
) give simplified example how to do this.

> Types used with std::vector must be nothrow-move-constructible or
> copy-constructible. If your type has a throwing move-ctor then vector will
> try to copy it, which causes an instantiation error.
If I remove copy-ctor and copy-assignment using "= delete" in that
paste.debian.org link and leave noexcept commented, then all will build
successfully. So, it seems for me vector uses the following algorithm:

if (has_noexcept_move_ctor)
  {
    use_noexcept_move_ctor ();
  }
else if (has_copy_ctor) // determined using trait. So if copy ctor is defined,
it will be used, even if it doesn't compile. If copy ctor is deleted using "=
delete", it will not be used
  {
    use_copy_ctor ();
  }
else
  {
    use_move_ctor ();
  }

Reply via email to