¿Existe una forma sencilla de convertir una enumeración de C++ en una cadena? [duplicar]
Supongamos que tenemos algunas enumeraciones con nombre:
enum MyEnum {
FOO,
BAR = 0x50
};
Lo que busqué en Google es un script (cualquier idioma) que escanea todos los encabezados de mi proyecto y genera un encabezado con una función por enumeración.
char* enum_to_string(MyEnum t);
Y una implementación con algo como esto:
char* enum_to_string(MyEnum t){
switch(t){
case FOO:
return "FOO";
case BAR:
return "BAR";
default:
return "INVALID ENUM";
}
}
El problema es realmente con enumeraciones con tipo de letra y enumeraciones de estilo C sin nombre. ¿Alguien sabe algo para esto?
EDITAR: La solución no debería modificar mi fuente, excepto las funciones generadas. Las enumeraciones están en una API, por lo que utilizar las soluciones propuestas hasta ahora simplemente no es una opción.
Las X-macros son la mejor solución. Ejemplo:
#include <iostream>
enum Colours {
# define X(a) a,
# include "colours.def"
# undef X
ColoursCount
};
char const* const colours_str[] = {
# define X(a) #a,
# include "colours.def"
# undef X
0
};
std::ostream& operator<<(std::ostream& os, enum Colours c)
{
if (c >= ColoursCount || c < 0) return os << "???";
return os << colours_str[c];
}
int main()
{
std::cout << Red << Blue << Green << Cyan << Yellow << Magenta << std::endl;
}
colores.def:
X(Red)
X(Green)
X(Blue)
X(Cyan)
X(Yellow)
X(Magenta)
Sin embargo, normalmente prefiero el siguiente método, para que sea posible modificar un poco la cadena.
#define X(a, b) a,
#define X(a, b) b,
X(Red, "red")
X(Green, "green")
// etc.
@hidroo: Sin el archivo extra:
#define SOME_ENUM(DO) \
DO(Foo) \
DO(Bar) \
DO(Baz)
#define MAKE_ENUM(VAR) VAR,
enum MetaSyntacticVariable{
SOME_ENUM(MAKE_ENUM)
};
#define MAKE_STRINGS(VAR) #VAR,
const char* const MetaSyntacticVariableNames[] = {
SOME_ENUM(MAKE_STRINGS)
};
Es posible que desee consultar GCCXML .
La ejecución de GCCXML en su código de muestra produce:
<GCC_XML>
<Namespace id="_1" name="::" members="_3 " mangled="_Z2::"/>
<Namespace id="_2" name="std" context="_1" members="" mangled="_Z3std"/>
<Enumeration id="_3" name="MyEnum" context="_1" location="f0:1" file="f0" line="1">
<EnumValue name="FOO" init="0"/>
<EnumValue name="BAR" init="80"/>
</Enumeration>
<File id="f0" name="my_enum.h"/>
</GCC_XML>
Puede utilizar cualquier idioma que prefiera para extraer las etiquetas Enumeration y EnumValue y generar el código que desee.