2009-10-26 8 views
6
namespace ValueType { 
    enum Enum { 
    Boolean = 0, 
    Float = 1, 
    Double, 
    SInt = 8, 
    SLong, 
    UInt = SInt + (1 <<4), 
    ULong = SLong + (1 << 4) 
    }; 
} 
+0

Ni siquiera sabía que era LEGAL ... bueno –

+3

No es realmente autorreferencial. Tiene algunos miembros que hacen referencia a miembros previamente definidos. Las reglas aquí son normales: una vez que está definido, es visible. –

+0

Actualicé la pregunta para reflejar su punto. Gracias. :) – Geoff

Respuesta

12

Sí, el requisito es que sea una expresión de constante integral. estándar El C++ incluye el siguiente ejemplo:

enum { d, e, f=e+2 }; 
+0

Cuando vi su respuesta y la anterior de Pavel, inmediatamente me acordé de la potenciación y la metaprogramación, ¿cómo no recuerdo eso? heh. Gracias. :) – Geoff

+0

Incluso es posible usar booleanos: ** enum {yes = true, no =! Yes}; ** – fmuecke

+0

Sí, de acuerdo con las reglas de C++, los * tipos integrales * incluyen "bool, char, wchar_t, los tipos enteros con signo y sin signo "y" bool values ​​se comportan como tipos integrales ". –

1

Como se ha señalado por Jerry, es legal.

En algunos casos excepcionales, es consciente de que el tipo de enumeradores solo se especifica después de que la enumeración esté completamente definida. El estándar dice lo siguiente sobre el tipo de las enumeraciones (7.2/4):

Cada enumeración define un tipo que es diferente de todos los demás tipos. Después del paréntesis de cierre de un enumerador de especificación, cada enumerador tiene el tipo de su enumeración. Antes del cierre de llave, el tipo de cada enumerador es el tipo de su valor de inicialización. Si se especifica un inicializador para un enumerador, el valor de inicialización tiene el mismo tipo que la expresión. Si no se especifica ningún inicializador para el primer enumerador, el tipo es un tipo integral no especificado. De lo contrario, el tipo es el mismo que el tipo del valor de inicialización del enumerador anterior a menos que el valor incrementado no sea representable en ese tipo, en cuyo caso el tipo es un tipo integral no especificado suficiente para contener el valor incrementado.

La sentencia de relieve se pueden mostrar en el siguiente ejemplo:

enum E { 
    E0   // Unspecified type 
    , E1 = E0-1 // -1, or MAX_UINT 
    , E2   // 0 or (MAX_UINT+1) 
}; 

Básicamente, el tipo elegido para E0 afecta el valor resultante de E1.

+0

Comprensible y lógico, no veo por qué alguien evitaría dar un valor inicial sin embargo. Hacer eso sin sentido lo pone a merced de la implementación del compilador. Caso en punto; en MSVC 2008, su E produce: E0 (0), E1 (-1), E2 (0). – Geoff

+0

Como con todo este tipo de comportamiento, las personas a veces solo asumen que el compilador hará lo que es razonable. Y, por supuesto, lo sensato es * lo * que esperan que suceda. –

Cuestiones relacionadas