nullopt_t
insufficiently constrainedSection: 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. Constantnullopt
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.
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. Constantnullopt
shall be initialized with an argument of literal type.