Constexpr inicializando miembro estático usando la función estática

Requerimientos

quiero unconstexpr valor (es decir, una constante de compilación) calculada a partir de unaconstexpr función. Y quiero ambos de estos ámbitos en el espacio de nombres de una clase, es decir, un método estático y un miembro estático de la clase.

Primer intento

Primero escribí esto de la manera obvia:

class C1 {
  constexpr static int foo(int x) { return x + 1; }
  constexpr static int bar = foo(sizeof(int));
};

g++-4.5.3 -std=gnu++0x dice a eso:

error: ‘static int C1::foo(int)’ cannot appear in a constant-expression
error: a function call cannot appear in a constant-expression

g++-4.6.3 -std=gnu++0x se queja

error: field initializer is not constant
Segundo intento

OK, pensé, tal vez tengo que sacar cosas del cuerpo de la clase. Así que intenté lo siguiente:

class C2 {
  constexpr static int foo(int x) { return x + 1; }
  constexpr static int bar;
};
constexpr int C2::bar = C2::foo(sizeof(int));

g++-4.5.3 Se compilará sin quejas. Desafortunadamente, mi otro código usa algunosfor Loops, así que tengo que tener al menos 4.6. Ahora que miro más de cerca ellista de apoyo, parece queconstexpr requeriría 4.6 también. Y cong++-4.6.3 yo obtengo

3:24: error: constexpr static data member ‘bar’ must have an initializer
5:19: error: redeclaration ‘C2::bar’ differs in ‘constexpr’
3:24: error: from previous declaration ‘C2::bar’
5:19: error: ‘C2::bar’ declared ‘constexpr’ outside its class
5:19: error: declaration of ‘const int C2::bar’ outside of class is not definition [-fpermissive]

Esto me suena realmente extraño. ¿Cómo se diferencian las cosas enconstexpr" ¿aquí? No tengo ganas de agregar-fpermissive ya que prefiero que mi otro código sea revisado rigurosamente. Moviendo elfoo La implementación fuera del cuerpo de la clase no tuvo ningún efecto visible.

Respuestas esperadas

¿Alguien puede explicar lo que está pasando aquí? ¿Cómo puedo lograr lo que estoy tratando de hacer? Me interesan principalmente las respuestas de los siguientes tipos:

Una forma de hacer que esto funcione en gcc-4.6.Una observación de que las versiones posteriores de gcc pueden tratar con una de las versiones correctamenteUn puntero a la especificación según la cual al menos una de mis construccionesdebería trabajar, de modo que pueda molestar a los desarrolladores de gcc para que realmente funcionenLa información de que lo que quiero es imposible de acuerdo con las especificaciones, preferiblemente con algún indicio de la razón detrás de esta restricción.

Otras respuestas útiles también son bienvenidas, pero tal vez no sean aceptadas tan fácilmente.

Respuestas a la pregunta(4)

Su respuesta a la pregunta