2009-08-25 14 views
8

En VC++ cuando necesito especificar una matriz con destino a una variable miembro de la clase lo hago de esta manera:¿Todos los compiladores de C++ permiten usar una variable de miembro de clase estática const int como una matriz enlazada?

class Class { 

private: 
    static const int numberOfColors = 16; 
    COLORREF colors[numberOfColors]; 
}; 

(por favor, no me digas sobre el uso de std :: vector aquí)

Este forma en que tengo una constante que puede usarse como una matriz vinculada y más tarde en el código de clase para especificar restricciones de instrucción de bucle y al mismo tiempo no es visible en ningún otro lado.

La pregunta es si este uso de las variables miembro static const int solo está permitido por VC++ o ¿está permitido normalmente por otros compiladores generalizados?

+8

"por favor, no me digas sobre el uso de std :: vector aquí" - no, eso no sería apropiado. Deberías usar 'std :: tr1 :: array'. ':)' – sbi

Respuesta

4

Sí, es 100% legal y debe ser portátil. El estándar C++ dice esto en 5.19 - Expresiones constantes "(énfasis mío):

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 miembro estático (9.4.2), y como argumentos de plantilla de tipo no integral o enumeración (14.3) .

constant-expression: 
    conditional-expression 

Una constante-expresión integral puede implicar sólo literales (2.13), enumeradores, las variables const o miembros de datos estáticos de integral o tipos de enumeración inicializa con expresiones constantes (8.5), parámetros de plantilla sin tipo de tipo integral o de enumeración, y tamaño de expresiones.

Dicho esto, parece que VC6 no lo admite. Ver StackedCrooked's answer para una buena solución. De hecho, generalmente prefiero el método enum StackedCrooked para este tipo de cosas.

Como un FYI, la técnica "static const" funciona en VC9, GCC 3.4.5 (MinGW), Comeau y Digital Mars.

Y no olvide que si se utiliza un miembro de "` static const '", podrás need a definition for it in addition to the declaration en sentido estricto. Sin embargo, prácticamente todos los compiladores le permitirán saltarse la definición en este caso.

1

Dejé de preocuparme por la portabilidad de hace años. Todavía hay compiladores que no lo admiten, pero no he encontrado ninguno recientemente.

13

Ese comportamiento es válido de acuerdo con el estándar C++. Cualquier compilador reciente debería ser compatible con.

6

Esto ha sido estándar C++ durante más de una década. Incluso es compatible con VC: ¿qué más podrías desear? (@Neil: ¿Qué pasa con SunCC? :^>)

6

Creo que Visual Studio 2005 y versiones posteriores lo admiten. El compilador XCode C++ también (esto es en realidad gcc).

Si quiere estar seguro, siempre puede usar el viejo enum hack que aprendí de Effective C++. Dice así:

class Class { 

private: 
    enum { 
     numberOfColors = 16 
    }; 
    COLORREF colors[numberOfColors]; 
}; 

Espero que esto ayude.

+0

Incluso VS 2k3 lo admite. – sharptooth

+0

El enum 'hack' no debería ser necesario si está tratando con código C++, pero si quiere que la declaración funcione en C o en VC++ 6, es mejor que el método más común para usar #define en mi opinión. –

2

Estoy bastante seguro de que esto también funcionará con gcc y Solaris, pero no puedo verificar esto en este momento.

En el futuro se podría extender la idea de esta manera:

template<int size> 
class Class { 
private: 
    COLORREF colors[size]; 
}; 

y utilizar de esta manera:

Class<5> c; 

de modo que usted no está limitado a exactamente un tamaño de búfer en la aplicación.

+0

Está utilizando un número mágico, que es lo que la pregunta intentaba evitar. –

+0

@Neil: Sin embargo, el número mágico 5 anterior podría reemplazarse por un 'static const int' de una clase a la que 'c' podría pertenecer. – quamrana

-1

Es posible responder a preguntas como esta haciendo referencia a la especificación ISO C++ pero la especificación es difícil de obtener para las personas y es más difícil de leer. creo que la respuesta más simple se basa en dos cosas:

  • Microsoft Visual Studio 2005 y hasta es relativamente conformes C++ aplicación. Si te permite hacer algo, es probable que sea su estándar.
  • Descargue algo como Code :: Blocks para obtener un compilador GCC para probar cosas. Si funciona en MS y GCC, lo más probable es que sea su estándar.
+0

La especificación es muy fácil de conseguir (por $ 30): http://stackoverflow.com/questions/81656/where-do-i-find-the-current-x-standard/83763#83763 Lectura de la especificación es una diferente historia, pero los programadores de C++ serios probablemente todavía deberían consultarlo de vez en cuando: http://stackoverflow.com/questions/1123455/should-every-c-programmer-read-the-iso-standard-to-become-professional –

13

Esto es válido C++ y la mayoría (¿todos?) Compiladores razonablemente modernos lo soportan.Si está utilizando impulso, puede obtener ayuda portátil para esta función en forma de BOOST_STATIC_CONSTANT macro:

class Class { 
private: 
    BOOST_STATIC_CONSTANT(int, numberOfColors = 16); 
    COLORREF colors[numberOfColors]; 
}; 

La macro se expande a static const int numberOfColors = 16 si el compilador soporta esto, de lo contrario se recurre a enum { numberOfColors=16 };.

3

Además de otras respuestas que puede utilizar la siguiente función no determinar el número de elementos en las matrices de forma estática alocated:

template<typename T, size_t length> 
size_t arrayLength(T (&a)[length]) 
{ 
    return length; 
} 
Cuestiones relacionadas