2009-02-05 11 views
57

Estoy usando el nombre completamente calificado de la enumeración dentro de un método en uno de mi clase. Pero recibo una advertencia del compilador que dice "advertencia C4482: extensión no estándar utilizada: enum 'Foo' utilizado en nombre calificado". En C++, ¿necesitamos usar enumeraciones sin el nombre calificado? Pero IMO, eso se ve feo.Usando enum dentro de los tipos - Advertencia del compilador C4482 C++

¿Alguna idea?

+5

que tienen experiencia en Java supongo;) :) Sí – hhafez

+1

. Java y C#. De hecho, esta es la única característica que me pareció feo en C++ en comparación con estos dos. –

+6

Si desea ese tipo de sintaxis, puede hacer el espacio de nombres sample {enum {BLAH0, BLAH1}} y luego simplemente hacer referencia a él como muestra :: BLAH0 – BigSandwich

Respuesta

53

Sí, las enumeraciones no crean un nuevo "espacio de nombres", los valores en la enumeración están directamente disponibles en el ámbito circundante. Entonces obtienes:

enum sample { 
    SAMPLE_ONE = 1, 
    SAMPLE_TWO = 2 
}; 

int main() { 
    std::cout << "one = " << SAMPLE_ONE << std::endl; 
    return 0; 
} 
11

Sí. Conceptualmente, enum define un tipo y los posibles valores de ese tipo. Aunque parezca natural, definir enum foo { bar, baz }; y luego referirse a foo::baz es lo mismo que referirse a int::1.

+0

pero, aunque puede usar foo :: baz (y recibir una advertencia), no puede usar int :: 1 –

+3

@ Simón: solo obtiene esa advertencia en Visual Studio, que la implementa como una extensión del compilador. GCC no lo hace; no, a menos que esté compilando como C++ 11 (donde es la sintaxis legal). –

35

Para que sea más limpia, reemplace:

enum Fruit { 

    ORANGE = 0, 
    BANANA = 1 

}; 

con

namespace Fruit { 

    enum { //no enum name needed 

     ORANGE = 0, 
     BANANA = 1 

    }; 

}; 

... 

int f = Fruit::BANANA; //No warning 
+2

Me gusta este enfoque. (Vengo de Java también). No entiendo la sabiduría de no nombrar enumeraciones que califiquen. Me interesaría saber el motivo. –

+8

No me gusta este enfoque, porque el tipo de variable no sugiere, que es una enumeración. – qub1n

14

Aunque algo sí contesta a la pregunta, no se refirió a la forma en que siempre he utilizado enumeraciones. Aunque solo son más o menos nombres para números, siempre los he usado para definir tipos que solo pueden tener ciertos valores.

Si la enumeración es parte de la clase, a continuación, que ayuda a los consumidores a identificar claramente una referencia enumeración:

class Apple { 
    enum Variety { 
    Gala, 
    GoldenDelicious, 
    GrannySmith, 
    Fuji 
    } 
    ... 
}; 

A continuación, los consumidores serían los casos de declarar capaces de la enumeración, pasan como parámetros, y los califica al hacer referencia a uno de los tipos.

unsigned int GetCountOfApples(Apple::Variety appleVariety); 
... 
fujiCnt = GetCountOfApples(Apple::Fuji); 

A veces quieren una enumeración fuera de una clase o dos enumeraciones de la misma clase, y se puede hacer algo parecido a lo que tenía Poy. Sin embargo, no podrás hacer referencia al tipo de enumeración, así que solo tienes que nombrarlo.

namespace Color { 
    enum ColorEnum { 
    Blue, 
    Red, 
    Black 
    }; 

Ahora, utilizando la enumeración y los valores funcionaría como:

Color::ColorEnum firstColor = Color::Blue; 
Color::ColorEnum secondColor = Color::Red; 

if(firstColor == secondColor) 
.... 

Ahora bien, si sucede que hay diferentes enumeraciones con el mismo nombre en ellos, siempre van a ser calificados con qué tipo son. Entonces podrías manejar lo que el jugador pregunta.

BananaColorEnum banCol = BananaColor::Yellow; 
TomatoColorEnum tomCol = TomatoColor::Yellow; 
7

La manera más limpia que he encontrado para hacer esto es la definición de la enumeración como tal

namespace Samples 
{ 
    enum Value 
    { 
     Sample1, 
     Sample2, 
     Sample3 
    }; 
} 
typedef Samples::Value Sample; 

Luego, en función y definiciones de variables se puede utilizar el typedef:

void Function(Sample eSample); 
Sample m_eSample; 

Y en su archivo .cpp puede usar el espacio de nombres para asignar variables:

void Function(Sample eSample) 
{ 
    m_eSample = Samples::Sample1; 
    eSample = Samples::Sample2; 
} 
8

namespace Company 
{ 
    typedef int Value; 
    enum 
    { 
     Microsoft= 0, 
     APPLE = 1, 
    }; 
}; 

namespace Fruit 
{ 
    typedef int Value; 
    enum 
    { 
     ORANGE = 0, 
     BANANA = 1, 
     APPLE = 2, 
    }; 
}; 

... 

Fruit::Value f = Fruit::BANANA; //No warning 
Company::Value f = Company::APPLE; //is different value then Fruit::APPLE 

Esto funciona en compilador de GCC y MS y Mac.Y la ventaja es que puede usar el operador del espacio de nombres y pasar conflictos. La pequeña desventaja es que en lugar de Fruit, debes escribir Fruit :: Value. es más útil en proyectos grandes cuando no sabes qué enumeraciones están en otra clase.

Si, en cambio, es posible utilizar C++ 11, es mucho más simple, porque la sintaxis enum :: namespace es posible.

+0

Su publicación sería más valiosa si pudiera agregarle alguna explicación. :) – ForceMagic

+2

Tengo una explicación de actualización. – qub1n

+0

Muy buena respuesta. Simple y limpio. – deeJ

1

Personalmente, creo que esto es un error del compilador. He estado usando C++ por mucho tiempo. Lamentablemente, no hay código de muestra en OP. La interpretación de una enumeración por parte de la gente de Java fue realmente correcta. El mío, era como esto ...

class Foo { 
    enum tMyEnum { eFirstVal = 0, eSecondVal = 1}; 
    // ... 
    tMyEnum m_myVal; 
}; 
void Foo::MyMethod() { 
    if(m_myVal == tMyEnum::eFirstVal) { 
// ... 
    } 
} 

También probé, Foo :: :: tMyEnum eFirstVal. Sin los calificadores, todo compilado.

0

Tuve el mismo problema y todavía no estoy usando C++ 11. Yo también prefiero espacios de nombres totalmente calificados.

Deshabilité esta advertencia en particular. Estoy seguro que la gente no les gusta la idea, pero algunos pueden estar agradecidos ..

#pragma warning(disable : 4482) 
Cuestiones relacionadas