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 expressionunless 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.[ 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 (7.2 dcl.enum), and as integral or enumeration non-type template arguments (14.3 temp.arg). -- end note ]
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 enumeration type and that conversion function shall beChange in 6.4.2 stmt.switch paragraph 2 as indicated:
constexpr. [ 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 be
an integralconstant expression (5.19 expr.const) . The integral constant expression is implicitly converted tothe 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; 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.
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:
an integralconstant expression ( including a constant expression of literal class type that can be used as an integral constant expression as described in5.19 expr.const) ; 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.
fora non-type template-parameter of integral or enumeration type, integral promotions (4.5) and integral conversions (4.7)are applied.