¿Existe una forma sencilla de convertir una enumeración de C++ en una cadena? [duplicar]

Resuelto Edu Felipe asked hace 16 años • 35 respuestas

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.

Edu Felipe avatar Oct 14 '08 22:10 Edu Felipe
Aceptado

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.
Marcin Koziuk avatar Oct 14 '2008 16:10 Marcin Koziuk

@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)
};
Jasper Bekkers avatar Oct 26 '2008 15:10 Jasper Bekkers

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.

Avdi avatar Oct 14 '2008 16:10 Avdi