This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Accepted as a DR at the November, 2022 meeting.]
According to 6.8.1 [basic.types.general] paragraph 10, a type is a literal type only if it satisfies the following:
A type is a literal type if it is:[Note 4: A literal type is one for which it might be possible to create an object within a constant expression. ... —end note]
- ...
- a possibly cv-qualified class type (Clause 11 [class]) that has all of the following properties:
- it has a constexpr destructor (9.2.6 [dcl.constexpr]),
- it is either a closure type (7.5.6.2 [expr.prim.lambda.closure]), an aggregate type (9.4.2 [dcl.init.aggr]), or has at least one constexpr constructor or constructor template (possibly inherited (9.9 [namespace.udecl]) from a base class) that is not a copy or move constructor,
- if it is a union, at least one of its non-static data members is of non-volatile literal type, and
- if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.
However, the normative rule disagrees with the note. Consider:
struct A { A(); }; union U { A a; constexpr U() {} constexpr ~U() {} };
It is certainly possible to create an object of type U in a constant expression, even though U is not a literal type.
In the suggested resolution, the aggregate type rule is intended to capture the fact that it is not possible for aggregate initialization of a non-empty union to leave no active member (and similarly for each anonymous union member in a non-union union-like class).
Suggested resolution [SUPERSEDED]:
Change in 6.8.1 [basic.types.general] paragraph 10 as follows:
A type is a literal type if it is:
- ...
- a possibly cv-qualified class type (Clause 11 [class]) that has all of the following properties:
- it has a constexpr destructor (9.2.6 [dcl.constexpr]),
- it
iseither
- is a closure type (7.5.6.2 [expr.prim.lambda.closure]),
- is an aggregate type (9.4.2 [dcl.init.aggr]) for which that type (if it is a union) or each of its anonymous union members (otherwise) either has at least one variant member of non-volatile literal type or has no variant members, or
- has at least one constexpr constructor or constructor template (possibly inherited (9.9 [namespace.udecl]) from a base class) that is not a copy or move constructor, and
if it is a union, at least one of its non-static data members is of non-volatile literal type, andif it is not a union,all of its non-static non-variant data members and base classes are of non-volatile literal types.
Proposed resolution (CWG telecon 2022-08-12) [SUPERSEDED]:
Change in 6.8.1 [basic.types.general] paragraph 10 as follows:
A type is a literal type if it is:
- ...
- a possibly cv-qualified class type (Clause 11 [class]) that has all of the following properties:
- it has a constexpr destructor (9.2.6 [dcl.constexpr]),
- all of its non-static non-variant data members and base classes are of non-volatile literal types, and
- it
iseither
- is a closure type (7.5.6.2 [expr.prim.lambda.closure]),
- is an aggregate type (9.4.2 [dcl.init.aggr]) for which that type (if it is a union) or each of its anonymous union members (otherwise) either has at least one variant member of non-volatile literal type or has no variant members, or
- has at least one constexpr constructor or constructor template (possibly inherited (9.9 [namespace.udecl]) from a base class) that is not a copy or move constructor
,.if it is a union, at least one of its non-static data members is of non-volatile literal type, andif it is not a union, all of its non-static data members and base classes are of non-volatile literal types.
Proposed resolution (approved by CWG 2022-11-09):
Change 6.8.1 [basic.types.general] paragraph 10 as follows:
A type is a literal type if it is:
...
a possibly cv-qualified class type (Clause 11 [class]) that has all of the following properties:
it has a constexpr destructor (9.2.6 [dcl.constexpr]),
all of its non-static non-variant data members and base classes are of non-volatile literal types, and
it
is either
is a closure type (7.5.6.2 [expr.prim.lambda.closure]),
an aggregate type (9.4.2 [dcl.init.aggr]),is an aggregate union type that has either no variant members or at least one variant member of non-volatile literal type,
is a non-union aggregate type for which each of its anonymous union members satisfies the above requirements for an aggregate union type, or
has at least one constexpr constructor or constructor template (possibly inherited (9.9 [namespace.udecl]) from a base class) that is not a copy or move constructor
,.
if it is a union, at least one of its non-static data members is of non-volatile literal type, and
if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.