I want a constexpr value (i.e. a compile-time constant) computed from a constexpr function. And I want both of these scoped
1) Ilya's example should be invalid code based on the fact that the static constexpr data member bar is initialized out-of-line violating the following statement in the standard:
9.4.2 [class.static.data] p3: ... A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression.
2) The code in MvG's question:
class C1 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar = foo(sizeof(int));
};
is valid as far as I see and intuitively one would expect it to work because the static member foo(int) is defined by the time processing of bar starts (assuming top-down processing). Some facts:
an invocation of an undefined constexpr function or an undefined constexpr constructor outside the definition of a constexpr function or a constexpr constructor;
class C1
{
constexpr static int foo() { return bar; }
constexpr static int bar = foo();
};
looks invalid but for different reasons and not simply because foo is called in the initializer of bar. The logic goes as follows:
but by bullet 9 in (5.19 p2) which bar does not satisfy because it is not yet initialized:
- an lvalue-to-rvalue conversion (4.1) unless it is applied to:
- a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression.
hence the lvalue-to-rvalue conversion of bar does not yield a constant expression failing the requirement in (9.4.2 p3).
an invocation of a constexpr function with arguments that, when substituted by function invocation substitution (7.1.5), do not produce a constant expression