This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2736. `nullopt_t` insufficiently constrained

Section: 22.5.4 [optional.nullopt] Status: C++17 Submitter: Tim Song Opened: 2016-06-17 Last modified: 2017-07-30

Priority: 2

View all other issues in [optional.nullopt].

View all issues with C++17 status.

Discussion:

22.5.4 [optional.nullopt]/2 requires of `nullopt_t` that

> Type `nullopt_t` shall not have a default constructor. It shall be a literal type. Constant `nullopt` shall be initialized with an argument of literal type.

This does not appear sufficient to foreclose the following implementation:

>     struct nullopt_t
>     {
>       constexpr nullopt_t(const nullopt_t&) = default;
>     };

>     constexpr nullopt_t nullopt(nullopt_t{});

- `nullopt_t` has no default constructor because it has a user-declared (copy) constructor;
- `nullopt_t` has a trivial destructor, is an aggregate, and is a literal type;
- `nullopt` has been initialized with an argument of literal type, to wit, `nullopt_t`.

But such a `nullopt_t` is still constructible from `{}` and so still makes `opt = {}` ambiguous.

[2016-08 Chicago]

This is related to LWG 2510.

Monday PM: Ville to provide updated wording

Fri AM: Moved to Tentatively Ready

Proposed resolution:

This wording is relative to N4606.

1. Edit 22.5.4 [optional.nullopt]/2 as indicated:

   > [Drafting note: `{}` can do one of three things for a class type: it may be aggregate initialization, it may call a default constructor, or it may call an initializer-list constructor (see 9.4.5 [dcl.init.list], 12.2.2.8 [over.match.list]). The wording below forecloses all three possibilities. — end drafting note]

   > -2- Type `nullopt_t` shall not have a default constructor or an initializer-list constructor. It shall not be an aggregate and shall be a literal type. Constant `nullopt` shall be initialized with an argument of literal type.