2736. nullopt_t insufficiently constrained

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

Priority: 2

View all issues with C++17 status.

Discussion:

23.6.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{});

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 23.6.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 11.6.4 [dcl.init.list], 16.3.1.7 [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.