2011-03-30 8 views
20

¿Es posible marcar un valor enum como obsoleto?C++ marque el valor enum como obsoleto?

p. Ej.

enum MyEnum { 
    firstvalue = 0 
    secondvalue, 
    thirdvalue, // deprecated 
    fourthvalue 
}; 

Una solución de segundo premio sería ifdef un MSVC y una solución de GCC.

+3

¿Qué quieres que suceda? Simplemente renómbrelo, y el compilador emitirá un error ... – Lindydancer

+3

@Lindydancer: Pero eso va un poco más allá de la depreciación, ¿no es así? Creo que el objetivo es permitir la compilación del código existente, pero emitir una advertencia sobre el recurso en desuso. –

+7

@Lindydancer: si hubiera sido suficiente, no habría sido necesario desaprobar las clases, funciones, tipos tampoco ... – moala

Respuesta

1

Uso de pragmas dependientes del compilador: Aquí está la documentación para Gcc y Visual Studio.

+3

Esto realmente no responde la pregunta, p. gcc permite que las funciones, tipos y variables se marquen como "obsoletos", pero no se menciona su aplicación a valores enum específicos. –

+2

Lamentablemente, gcc no le permite especificar un atributo a un valor enum, solo en todo el tipo de enumeración. Por supuesto, podría crear dos enumeraciones (una con los valores en desuso) como una solución alternativa, pero luego, por supuesto, tendrían diferentes tipos. – Damon

+0

@Damon: tal vez con una referencia, eso hubiera sido una gran respuesta. – moala

1

Es posible que pueda utilizar algunos macro hackers.

enum MyEnum { 
    firstvalue = 0 
    secondvalue, 
    real_thirdvalue, // deprecated 
    fourthvalue 
}; 

template <MyEnum v> 
struct real_value 
{ 
    static MyEnum value() 
    { 
     1 != 2U; // Cause a warning in for example g++. Leave a comment behind for the user to translate this warning into "thirdvalue is deprecated" 
     return v; 
    } 
}; 

#define thirdvalue (real_value<real_thirdvalue>::value()); 

Esto no funcionará en un contexto cuando se necesita una constante.

+0

No tengo idea de si esto funciona, pero +1 para piratería de mente pura y sangrienta. ;-) –

+0

¿Por qué irías tan salvaje? – lpapp

13

usted puede hacer esto:

enum MyEnum { 
    firstvalue = 0, 
    secondvalue, 
    thirdvalue, // deprecated 
    fourthvalue 
}; 
#pragma deprecated(thirdvalue) 

continuación, cuando cada vez que se utiliza la variable, el compilador de salida lo siguiente:

warning C4995: 'thirdvalue': name was marked as #pragma deprecated 

EDITAR
Esto parece un poco hacky y yo no tengo un compilador de GCC para confirmar (¿alguien podría hacer eso por mí?) pero debería funcionar:

enum MyEnum { 
    firstvalue = 0, 
    secondvalue, 
#ifdef _MSC_VER 
    thirdvalue, 
#endif 
    fourthvalue = secondvalue + 2 
}; 

#ifdef __GNUC__ 
__attribute__ ((deprecated)) const MyEnum thirdvalue = MyEnum(secondvalue + 1); 
#elif defined _MSC_VER 
#pragma deprecated(thirdvalue) 
#endif 

Es una combinación de mi respuesta y respuesta MSalters'

+0

¿Sabes si es posible hacerlo mejor? sin "entre" #ifdef _MSC_VER? Intento escribir una macro para manejarla multiplataforma, pero eso lo hace un poco más desagradable para el usuario final. Sería bueno si el usuario final pudiera usar una macro independiente. – lpapp

+0

Otro punto para tenerlo sin ifdef, podría potencialmente romper la compatibilidad binaria basada en la representación enum subyacente en la plataforma dada. – lpapp

3

Bueno, ya que estamos en cortes macro ya, aquí está la mía :-)

enum MyEnum 
{ 
foo, 
bar, 
baz 
}; 

typedef __attribute__ ((deprecated))MyEnum MyEnum_deprecated; 
#define bar ((MyEnum_deprecated) bar) 

int main() 
{ 
    int a = foo; // yuck, why did C++ ever allow that... 
    int b = bar; 

    MyEnum c = foo; 
    MyEnum d = bar; 

    return 0; 
} 

Esto funciona con gcc, y lo hace no requiere que rompa la seguridad del tipo. Desafortunadamente, sigue abusando de tu código con macros, entonces meh. Pero por lo que pude entender, es tan bueno como se pone.

La propuesta hecha por Tom es mucho más limpia (funciona para MSVC, supongo), pero desafortunadamente el único mensaje que le dará gcc es "ignorar pragma".

+0

funcionará ahora: P – Tom

+0

¿Funcionará correctamente con una enumeración dentro de una clase o espacio de nombres? – lpapp

+0

Dado que es un macro hack, "funcionará" con enumeraciones dentro de espacios de nombres, incluso mejor de lo que desearía. Esa es la desventaja de las macros, simplemente reemplazan el texto y no respetan los espacios de nombres. Desafortunadamente no puedes asignar un atributo a un solo enumerador, solo a la cosa completa. Entonces tienes que hacer un tipo de truco para que funcione. – Damon

3

Puede declarar constantes de enumeración fuera una declaración de enumeración:

enum MyEnum { 
    firstvalue = 0 
    secondvalue, 
    thirdvalue 
}; 
__attribute__ ((deprecated)) const MyEnum fourthvalue = MyEnum(thirdvalue + 1); 
+0

Sin embargo, esto no funcionará para msvc ni con las enumeraciones de clase C++ 11. – lpapp

+0

También se rompe si el compilador elige un tipo subyacente para 'MyEnum' que no es lo suficientemente grande como para contener el valor que asigna (' thirdvalue + 1'). –

0

tengo una solución (inspirado de Mark B) que hace uso de realce/serialización/static_warning.hpp. Sin embargo, el mío permite que thirdvalue se use como una constante simbólica. También produce advertencias para cada lugar donde alguien intente usar thirdvalue.

#include <boost/serialization/static_warning.hpp> 

enum MyEnum { 
    firstvalue = 0, 
    secondvalue, 
    deprecated_thirdvalue, // deprecated 
    fourthvalue 
}; 

template <int line> 
struct Deprecated 
{ 
    BOOST_SERIALIZATION_BSW(false, line); 
    enum {MyEnum_thirdvalue = deprecated_thirdvalue}; 
}; 

#define thirdvalue (static_cast<MyEnum>(Deprecated<__LINE__>::MyEnum_thirdvalue)) 

enum {symbolic_constant = thirdvalue}; 

int main() 
{ 
    MyEnum e = thirdvalue; 
} 

En GCC me sale advertencias de que en última instancia apuntan a las líneas que contienen culpable thirdvalue.

Tenga en cuenta que el uso de la plantilla Deprecated hace que una línea de salida del compilador "instanciado aquí" muestre dónde se utiliza la enumeración en desuso.

Si puede encontrar una manera de generar una advertencia de forma portátil dentro de la plantilla Deprecated, entonces puede eliminar la dependencia de Boost.

Cuestiones relacionadas