The Standard requires (section 9.4.2):
A
static
data member of literal type can be declared in the class definition with theconstexpr
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.
In your “second attempt” and the code in Ilya’s answer, the declaration doesn’t have a brace-or-equal-initializer.
Your first code is correct. It’s unfortunate that gcc 4.6 isn’t accepting it, and I don’t know anywhere to conveniently try 4.7.x (e.g. ideone.com is still stuck on gcc 4.5).
This isn’t possible, because unfortunately the Standard precludes initializing a static constexpr
data member in any context where the class is complete. The special rule for brace-or-equal-initializers in 9.2p2 only applies to non-static data members, but this one is static.
The most likely reason for this is that constexpr
variables have to be available as compile-time constant expressions from inside the bodies of member functions, so the variable initializers are completely defined before the function bodies — which means the function is still incomplete (undefined) in the context of the initializer, and then this rule kicks in, making the expression not be a constant expression:
an invocation of an undefined
constexpr
function or an undefinedconstexpr
constructor outside the definition of aconstexpr
function or aconstexpr
constructor;
Consider:
class C1
{
constexpr static int foo(int x) { return x + bar; }
constexpr static int bar = foo(sizeof(int));
};