The right way
Before we begin legal work with the language, the right approach is to do it the other way around. In the header file:
class Foo { static constexpr int IntArray[] = { 1, 2, 3, 4 }; };
And then in the source file:
constexpr int Foo::IntArray[];
If you declare a static constexpr class data member in a class definition, you must initialize it then and there. This is not necessary for static const data members. If you use the static constexpr data element static constexpr in the program, you must give a definition similar to the above in exactly one source file without an initializer.
What does (draft) standard mean
The sample code in the question is a bad style, and at least one compiler seems to reject it, but actually it seems to conform to the C ++ 14 project standard. [ Dcl / constexpr ] says:
The constexpr should only be applied to the definition of a variable or variable template, the declaration of a function or function template, or the declaration of a static data item of literal type. If any declaration of a function, function template, or variable template has a constexpr , then all of its declarations must contain a constexpr .
Note whose declarations, without limitation, are not , all must contain a constexpr .
Further in the same section:
A constexpr qualifier used in declaring an object declares the object as const . Such an object must be of literal type and must be initialized. [...]
But see also [ class.static.data ]:
If the non volatile const static data member is of the type of an integral or enumeration, its declaration in the class definition may indicate a boolean or equal-initializer, in which each condition of the initializer, which is an expression-expression is a constant expression. A static literal data member can be declared in the class definition using the constexpr ; if so, his declaration specifies a logical or equal-initializer, in which each initializing clause, which is an assignment expression, is a constant expression. [Note. In both cases, the term can be displayed in constant expressions. - end note] An element must still be defined in the namespace scope, if used in the odr program, and the namespace scope definition should not contain an initializer.
In this context, odr in “odr-used” means a rule with one definition and means “whose name is displayed as a potentially evaluated expression”. ([basic.def.odr]) The last sentence means that if you declare static constexpr int foo = 0; in the class definition, and later you use it in the expression, for example int x = MyClass::foo; , then one and only one source file must have a string of type constexpr int MyClass::foo; in it, so the linker knows which file object to insert it into.