Change in 5.19 expr.const paragraph 2 as indicated:
A conditional-expression is aChange in 5.19 expr.const paragraph 3 as indicated:constant expressioncore constant expression unless it involves one of the following ...
- ...
an array-to-pointer conversion (4.2 conv.array) that is applied to a glvalue that does not designate an object with static storage duration;a unary operator & (5.3.1 expr.unary.op) that is applied to an lvalue that does not designate an object with static storage duration;- an id-expression that refers to a variable or data member of reference type [ Footnote: ... ];
- ...
Change in 5.19 expr.const paragraph 5 as indicated:A constant expression is an integral constant expression if it is of integral or enumeration type.A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. An integral constant expression is a literal constant expression of integral or unscoped enumeration type. [ Note: such expressions may be used as array bounds (8.3.4 dcl.array, 5.3.4 expr.new),as case expressions (6.4.2 stmt.switch),as bit-field lengths (9.6 class.bit), as enumerator initializers if the underlying type is not fixed (7.2 dcl.enum), as null pointer constants (4.10 conv.ptr), and as alignments (7.6.2 dcl.align)and as integral or enumeration non-type template arguments (14.3 temp.arg). -- end note ] A converted constant expression of type T is a literal constant expression, implicitly converted to type T, where the implicit conversion (if any) is permitted in a literal constant expression and the implicit conversion sequence contains only user-defined conversions, lvalue-to-rvalue conversions (4.1 conv.lval), integral promotions (4.5 conv.prom), and integral conversions (4.7 conv.integral) other than narrowing conversions (8.5.4 dcl.init.list). [ Note: such expressions may be used as case expressions (6.4.2 stmt.switch), as enumerator initializers if the underlying type is fixed (7.2 dcl.enum), and as integral or enumeration non-type template arguments (14.3 temp.arg). ] A reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function. An address constant expression is a prvalue core constant expression of pointer type that evaluates to the address of an object with static storage duration, to the address of a function, or to a null pointer value, or a prvalue core constant expression of typestd::nullptr_t
. Collectively, literal constant expressions, reference constant expressions, and address constant expressions are called constant expressions.
If an expression of literal class type is used in a context where an integral constant expression is required, then that class type shall have a single non-explicit conversion function to an integral or unscoped enumeration type and that conversion function shall beChange in 6.4.2 stmt.switch paragraph 2 as indicated:constexprconstexpr
. [ Example: ... ]
Any statement within the switch statement can be labeled with one or more case labels as follows:Editing note: This allows scoped enumerators as case labels given that they're no longer part of "integral constant expression"; see above. Since we know the exact target type, we can use that information to disambiguate several conversions from a literal class type.case constant-expression :where the constant-expression shall bean integrala converted constant expression (5.19 expr.const). The integral constant expression is implicitly converted toof the promoted type of the switch condition.
Change in 7.2 dcl.enum paragraph 2 as indicated:
... An enumerator-definition with = gives the associated enumerator the value indicated by the constant-expression.Change in 7.2 dcl.enum paragraph 5 as indicated:The constant-expression shall be an integral constant expression (5.19 expr.const).If the first enumerator has no initializer, the value of the corresponding constant is zero. ...
... If the underlying type is fixed, the type of each enumerator prior to the closing brace is the underlying type and the constant-expression in the enumerator-definition shall be a converted constant expression of the underlying type (5.19 expr.const); if the initializing value of an enumerator cannot be represented by the underlying type, the program is ill-formed. If the underlying type is not fixed, the type of each enumerator is the type of its initializing value:Change in 14.3.2 temp.arg.nontype paragraph 1 as indicated:
- If an initializer is specified for an enumerator, the initializing value has the same type as the expression and the constant-expression shall be an integral constant expression (5.19 expr.const).
- ...
A template-argument for a non-type, non-template template-parameter shall be one of:Change in 14.3.2 temp.arg.nontype paragraph 5 as indicated:
- for a non-type template-parameter of integral or enumeration type,
an integrala converted constant expression (including a constant expression of literal class type that can be used as an integral constant expression as described in5.19 expr.const) of the type of the template-parameter; or- ...
The following conversions are performed on each expression used as a non-type template-argument. If a non-type template-argument cannot be converted to the type of the corresponding template-parameter then the program is ill-formed.Editing note: The changes to 5.19 prohibit that a scoped enumerator could be used as an array bound, without a cast. Also, previously, a scoped enumerator could be used to initialize an enumerator of another scoped enumeration type (because it used to be covered by "integral constant expression"), which is surprising. Switch statements and template arguments are special in that the specific target type is actually known, and scoped enumerations are no problem.
forFor a non-type template-parameter of integral or enumeration type,integral promotions (4.5) and integral conversions (4.7)conversions permitted in a converted constant expression (5.19 expr.const) are applied.- ...