Is there a simple way to convert C++ enum to string?

You may want to check out GCCXML.

Running GCCXML on your sample code produces:

<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>

You could use any language you prefer to pull out the Enumeration and EnumValue tags and generate your desired code.


X-macros are the best solution. Example:

#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;
}

colours.def:

X(Red)
X(Green)
X(Blue)
X(Cyan)
X(Yellow)
X(Magenta)

However, I usually prefer the following method, so that it's possible to tweak the string a bit.

#define X(a, b) a,
#define X(a, b) b,

X(Red, "red")
X(Green, "green")
// etc.

What I tend to do is create a C array with the names in the same order and position as the enum values.

eg.

enum colours { red, green, blue };
const char *colour_names[] = { "red", "green", "blue" };

then you can use the array in places where you want a human-readable value, eg

colours mycolour = red;
cout << "the colour is" << colour_names[mycolour];

You could experiment a little with the stringizing operator (see # in your preprocessor reference) that will do what you want, in some circumstances- eg:

#define printword(XX) cout << #XX;
printword(red);

will print "red" to stdout. Unfortunately it won't work for a variable (as you'll get the variable name printed out)


@hydroo: Without the extra file:

#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)
};