Yes, it is poorly formed. That's why:
Function A constexpr must be defined (not just declared) before being used in a constant expression.
So for example:
constexpr int f(); // declare f constexpr int x = f(); // use f - ILLEGAL, f not defined constexpr int f() { return 5; } // define f, too late
function definitions inside the class specifier (as well as initializers and default parameters) are essentially parsed in the order they were defined outside the class.
So this is:
struct X { constexpr static int size() { return 5; } static const int array[size()]; };
It is analyzed in the following order:
struct X { constexpr inline static int size();
That is, parsing function bodies is delayed until a class specifier is specified.
The purpose of this deferral of parsing a body function is that function bodies can redirect reference classes not yet declared at this point, and therefore they can use their own class as a full type:
struct X { void f() { T t; } typedef int T; };
Compared to the namespace scope:
void f() { T t; } typedef int T;
In POINT A , the compiler does not yet have a definition for size() , so it cannot call it. To execute compilation time, constexpr functions must be defined before they are used in the translation block before being called during compilation, otherwise the compiler will have to make several passes just to βlinkβ the constant expressions for evaluation.
Andrew Tomazos
source share