¿Por qué no están permitidos los flotadores estáticos?

Tengo una clase que básicamente solo contiene un montón de definiciones constantes usadas a través de mi aplicación. Sin embargo, por alguna razón, long s comstack pero float s no:

 class MY_CONSTS { public : static const long LONG_CONST = 1; // Compiles static const float FLOAT_CONST = 0.001f; // C2864 }; 

Da el siguiente error:

 1>c:\projects\myproject\Constant_definitions.h(71) : error C2864: 'MY_CONSTS::FLOAT_CONST' : only static const integral data members can be initialized within a class 

¿Me estoy perdiendo de algo?

Para responder la pregunta real que hizo: “porque el estándar así lo dice”.

Solo las variables de tipos estáticos, constantes e integrales (incluidas las enumeraciones) pueden inicializarse dentro de una statement de clase. Si un comstackdor admite la inicialización en línea de flotadores, es una extensión. Como otros señalaron, la forma de manejar variables estáticas, constantes y no integrales es definirlas e inicializarlas en el archivo fuente correspondiente de la clase (no en el encabezado).

Norma C ++ Sección 9.2 “Miembros de la clase” ítem 4:

Un miembro declarador puede contener un inicializador constante solo si declara un miembro estático (9.4) de tipo const integral o const enumeration, ver 9.4.2.

Sección 9.4.2 Elemento “Miembros de datos estáticos” 2:

Si un miembro de datos estático es de tipo const integral o const enumeration, su statement en la definición de clase puede especificar un constante-inicializador que debe ser una expresión de constante integral (5.19). En ese caso, el miembro puede aparecer en expresiones constantes integrales. El miembro se definirá de todos modos en un ámbito de espacio de nombres si se utiliza en el progtwig y la definición de ámbito de espacio de nombres no contendrá un inicializador .

Debe inicializarlos en el cuerpo de uno de sus archivos cpp:

 class MY_CONSTS { public : static const long LONG_CONST = 1; // Compiles static const float FLOAT_CONST; }; const float MY_CONSTS::FLOAT_CONST = 0.001f; 

Vea la explicación de Stroustrup . Cita relevante:

Por lo general, una clase se declara en un archivo de cabecera y, por lo general, un archivo de cabecera se incluye en muchas unidades de traducción. Sin embargo, para evitar reglas de enlazador complicadas, C ++ requiere que cada objeto tenga una definición única. Esa regla se rompería si C ++ permitiera la definición dentro de la clase de las entidades que debían almacenarse en la memoria como objetos. Consulte D & E para obtener una explicación de las ventajas de diseño de C ++.

El razonamiento bajo la redacción estándar que otros han dado es el mismo para el cual los argumentos de la plantilla no pueden ser números en coma flotante. Para obtener un resultado consistente, necesitará que el comstackdor implemente la misma evaluación que la realizada en tiempo de comstackción, y eso puede ser complicado para el comstackdor cruzado y en el caso donde el progtwig se reproduce con el modo de redondeo.

Desde la memoria, en C ++ 0X, la noción de expresión constante se ha extendido y su código sería válido (pero no especificado en el resultado de las expresiones constantes de coma flotante son las mismas cuando se evalúan en tiempo de ejecución o en tiempo de comstackción )

qué pasa:

 class MY_CONSTS { public : static const long LONG_CONST; static const float FLOAT_CONST; }; const long MY_CONSTS::LONG_CONST = 1; const float MY_CONSTS::FLOAT_CONST = 0.001f; 

(aunque no puedo dar ninguna explicación de este caso específico …)

Del estándar 9.4.2 / 4

Si un miembro de datos estático es de tipo const integral o const enumeration, su statement en la definición de clase puede especificar un constante-inicializador que debe ser una expresión de constante integral (5.19). En ese caso, el miembro puede aparecer en expresiones constantes integrales. El miembro aún se definirá en un ámbito de espacio de nombres si se usa en el progtwig y la definición del scope del espacio de nombres no contendrá un inicializador.

Y 5.19 / 1:

En varios lugares, C + + requiere expresiones que evalúen una constante integral o de enumeración: como límites de matriz (8.3.4, 5.3.4), como expresiones de caso (6.4.2), como longitudes de campo de bit (9.6), como Inicializadores de enumerador (7.2), como inicializadores de miembros estáticos (9.4.2), y como argumentos de plantilla de tipo no integral o enumeración (14.3). expresión-constante: expresión-condicional Una expresión-constante integral puede implicar solo literales (2.13), enumeradores, variables const o miembros de datos estáticos de tipos integrales o de enumeración inicializados con expresiones constantes (8.5), parámetros de plantilla sin tipo de integral o enumeración tipos y tamaño de expresiones. Los literales flotantes (2.13.3) solo pueden aparecer si se convierten a tipos integrales o de enumeración . Solo se pueden usar conversiones de tipos a tipos integrales o de enumeración. En particular, excepto en el tamaño de expresiones, funciones, objetos de clase, punteros o referencias no