Constexpr does not work if a function is declared inside a class

I am using g ++ 4.8.0 which does not previously contain constexpr error. So the code below works fine :

 constexpr int size() { return 5; } int array[size()]; int main () {} 

However, if I enclose the variable inside a class as static , then it gives a compiler error :

 struct X { constexpr static int size() { return 5; } static const int array[size()]; }; int main () {} 

Here is the error:

error: the size of the array array is not an integral constant expression

Is it forbidden to use constexpr in this way or another g ++ error?

+9
c ++ c ++ 11 g ++ compiler-errors constexpr
source share
2 answers

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(); // function body defered static const int array[size()]; // <--- POINT A }; constexpr inline int X::size() { return 5; } 

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; /* OK */ } typedef int T; }; 

Compared to the namespace scope:

 void f() { T t; /* error, T not declared */ } 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.

+12
source share
+5
source share

All Articles