Certain contexts require expressions that satisfy additional requirements as detailed in this subclause; other contexts have different semantics depending on whether or not an expression satisfies these requirements. Expressions that satisfy these requirements, assuming that copy elision is performed, are called constant expressions. [ Note: Constant expressions can be evaluated during translation. — end note ]
constant-expression: conditional-expression
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
this, except in a constexpr function or a constexpr constructor that is being evaluated as part of e;
an invocation of a function other than a constexpr constructor for a literal class, a constexpr function, or an implicit invocation of a trivial destructor ([class.dtor]) [ Note: Overload resolution is applied as usual — end note ] ;
an invocation of an undefined constexpr function or an undefined constexpr constructor;
an invocation of an instantiated constexpr function or constexpr constructor that fails to satisfy the requirements for a constexpr function or constexpr constructor;
an expression that would exceed the implementation-defined limits;
an operation that would have undefined behavior as specified in Clauses [intro] through [cpp] of this International Standard [ Note: including, for example, signed integer overflow (Clause [expr]), certain pointer arithmetic ([expr.add]), division by zero, or certain shift operations — end note ] ;
an lvalue-to-rvalue conversion unless it is applied to
a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression, or
a non-volatile glvalue that refers to a subobject of a string literal, or
a non-volatile glvalue that refers to a non-volatile object defined with constexpr, or that refers to a non-mutable subobject of such an object, or
a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;
an lvalue-to-rvalue conversion that is applied to a glvalue that refers to a non-active member of a union or a subobject thereof;
an invocation of an implicitly-defined copy/move constructor or copy/move assignment operator for a union whose active member (if any) is mutable, unless the lifetime of the union object began within the evaluation of e;
an assignment expression or invocation of an assignment operator ([class.copy]) that would change the active member of a union;
an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
it is initialized with a constant expression or
its lifetime began within the evaluation of e;
in a lambda-expression, a reference to this or to a variable with automatic storage duration defined outside that lambda-expression, where the reference would be an odr-use; [ Example:
void g() { const int n = 0; [=] { constexpr int i = n; constexpr int j = *&n; }; }
— end example ] [ Note: If the odr-use occurs in an invocation of a function call operator of a closure type, it no longer refers to this or to an enclosing automatic variable due to the transformation ([expr.prim.lambda.capture]) of the id-expression into an access of the corresponding data member. [ Example:
auto monad = [](auto v) { return [=] { return v; }; }; auto bind = [](auto m) { return [=](auto fvm) { return fvm(m()); }; }; static_assert(bind(monad(2))(monad)() == monad(2)());
— end example ] — end note ]
a conversion from type cv void* to a pointer-to-object type;
a dynamic cast;
modification of an object ([expr.ass], [expr.post.incr], [expr.pre.incr]) unless it is applied to a non-volatile lvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;
a typeid expression whose operand is a glvalue of a polymorphic class type;
a relational or equality operator where the result is unspecified; or
If e satisfies the constraints of a core constant expression, but evaluation of e would evaluate an operation that has undefined behavior as specified in Clauses [library] through [thread] of this International Standard, it is unspecified whether e is a core constant expression.
[ Example:
int x; struct A { constexpr A(bool b) : m(b?42:x) { } int m; }; constexpr int v = A(true).m; constexpr int w = A(false).m; constexpr int f1(int k) { constexpr int x = k; return x; } constexpr int f2(int k) { int x = k; return x; } constexpr int incr(int &n) { return ++n; } constexpr int g(int k) { constexpr int x = incr(k); return x; } constexpr int h(int k) { int x = incr(k); return x; } constexpr int y = h(1);
— end example ]
An integral constant expression is an expression of integral or unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. [ Note: Such expressions may be used as bit-field lengths, as enumerator initializers if the underlying type is not fixed ([dcl.enum]), and as alignments. — end note ]
A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant expression and the implicit conversion sequence contains only
user-defined conversions,
integral conversions other than narrowing conversions,
null pointer conversions from std::nullptr_t,
null member pointer conversions from std::nullptr_t, and
and where the reference binding (if any) binds directly. [ Note: Such expressions may be used in new expressions, as case expressions, as enumerator initializers if the underlying type is fixed, as array bounds, and as non-type template arguments. — end note ] A contextually converted constant expression of type bool is an expression, contextually converted to bool, where the converted expression is a constant expression and the conversion sequence contains only the conversions above.
A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints:
if the value is an object of class type, each non-static data member of reference type refers to an entity that is a permitted result of a constant expression,
if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object ([expr.add]), the address of a function, or a null pointer value, and
if the value is an object of class or array type, each subobject satisfies these constraints for the value.
An entity is a permitted result of a constant expression if it is an object with static storage duration that is either not a temporary object or is a temporary object whose value satisfies the above constraints, or it is a function.
[ Note: Since this International Standard imposes no restrictions on the accuracy of floating-point operations, it is unspecified whether the evaluation of a floating-point expression during translation yields the same result as the evaluation of the same expression (or the same operations on the same values) during program execution.89 [ Example:
bool f() { char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; int size = 1 + int(1 + 0.2 - 0.1 - 0.1); return sizeof(array) == size; }
It is unspecified whether the value of f() will be true or false. — end example ] — end note ]
If an expression of literal class type is used in a context where an integral constant expression is required, then that expression is contextually implicitly converted to an integral or unscoped enumeration type and the selected conversion function shall be constexpr. [ Example:
struct A { constexpr A(int i) : val(i) { } constexpr operator int() const { return val; } constexpr operator long() const { return 43; } private: int val; }; template<int> struct X { }; constexpr A a = 42; X<a> x; int ary[a];
— end example ]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4