Using C++11 variadic templates to initialize Enum To String Map

Viewed 729

I think its possible to use Variadic template arguments introduced in C++11 for initializing a map which the keys are ints and values are string notation of given arguments.

If its possible i could simply create a map from Enum name to its string representation like this :

auto map = EnumStringMap<EnumType::Type1, EnumType::Type2>();

I can initialize a list with enum int representations via this template

template<typename... Ts> auto enumList(Ts... args){
    QList<int> res = {args...};
    return res;
}

auto enums =  enumList<int, int>(Enums::Enum1, Enums::Enum2);

I think it should be possible with STRINGFY C macro to get string representation of expression

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

But i can't figure out how to convert type name or type value to its string representation, so is it possible at all? My goal is to produce a map of which hold the string representation of enumrations in compile time.

The approaches like MOC used by qt isn't right for me, because i should enclose the enums in QObject which is heavy and non copyable.

1 Answers

The macros are handled by the preprocessor, before any C++ compilation. Therefore you cannot use a macro inside a function to retrieve the C++ name of an enum value.

Most solutions are based on macro used at the point where the enum is defined. There are many implementation available on the Internet and it generally do something like that:

#define MY_ENUM(a, b, c) enum a {b , c} \
Map<a, string> mymap = {{b, STRINGIFY(b)}, {b, STRINGIFY(b)}};

MY_ENUM(Color, Red, Blue)
MY_ENUM(Align, Left, Right)

Another approach is using meta compilers, that will process the C++ code to generate more code. This is what Qt does with its moc, and since you tagged your question with Qt, it might be the best way to go for you..

class FooBar : public QObject {
  Q_OBJECT
public:
  enum Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
  Q_ENUM(Action) // Not Q_ENUMS !!!

  static QString convert(Action a) {
    auto metaEnum = QMetaEnum::fromType<Action>();
    return metaEnum.valueToKey(a);
  }
};

This has some constraints, like the fact that the enum must be defined in a QObject (or a Q_GADGET). You can find out more in Qt documentation. For how it is done you can see Woboq article.

Related