2

I have a basic question about C++ enums.

Here is an enum:

enum Names {
    Tim     =       0x1,
    Bob     =       0x2,
    Jim     =       0x4
};

If I receive a value (for instance 0x4) I would like to print the related name: Jim.

Is there a way to do it? Something like Names.key(0x04) ? I know this exists in Java.

Thanks

Maxbester
  • 2,435
  • 7
  • 42
  • 70
  • 'I know this exists in Java', but Java is a language with reflection, C++ isn't. There is no automatic way to do this, you have to do the work yourself. – john Apr 02 '13 at 14:59
  • For examples on HOW to do this yourself, see http://stackoverflow.com/questions/6281461/enum-to-string-c – Scott Hunter Apr 02 '13 at 15:00
  • This previous thread gives you a ton of options http://stackoverflow.com/questions/3342726/c-print-out-enum-value-as-text – Shafik Yaghmour Apr 02 '13 at 15:01

5 Answers5

2

No, you can't. That's possible in Java due to reflection, a feature that does not exists in C++.

The best you can do is to store the names in a map:

std::map<Names, std::string> names_string = {
    { Tim, "Tim"},
    { Bob, "Bob"}
    // .....
};

std::cout << "Tim's enum: " << names_string[Tim] << std::endl;
mfontanini
  • 21,410
  • 4
  • 65
  • 73
2

As many people said, this is not possible in vanilla C++. But if you use Qt you can define enums that are registered to the Qt meta system, so you can retrieve enum info during runtime.

The QMetaEnum class provides meta-data about an enumerator.

Use name() for the enumerator's name. The enumerator's keys (names of each enumerated item) are returned by key(); use keyCount() to find the number of keys. isFlag() returns whether the enumerator is meant to be used as a flag, meaning that its values can be combined using the OR operator.

The conversion functions keyToValue(), valueToKey(), keysToValue(), and valueToKeys() allow conversion between the integer representation of an enumeration or set value and its literal representation. The scope() function returns the class scope this enumerator was declared in.

 class MyClass : public QObject
 {
     Q_OBJECT
     Q_ENUMS(Priority)

 public:
     MyClass(QObject *parent = 0);
     ~MyClass();

     enum Priority { High, Low, VeryHigh, VeryLow };
     void setPriority(Priority priority);
     Priority priority() const;
 };

Since the whole mechanism uses the Qt meta system, you can only use this approach only for enums, members of QObject derived classes.

dtech
  • 47,916
  • 17
  • 112
  • 190
  • Good! But I guess I cannot build a `QMetaEnum` from a basic `enum`, right? – Maxbester Apr 02 '13 at 15:07
  • You can but you must use a macro to register it to the meta system. But you will have to compile your project with that, otherwise it is not possible to get access during runtime. Update to my answer. – dtech Apr 02 '13 at 15:08
0

No, there is no way to do this in C++. Firstly, the names of the enum are compiled out. If you want to get to the enum type from the integer, you can cast.

Analogously if you had

Foo foo = new Foo();
String name = "John";
int age = 23;

There is no way to obtain the variable names in C++.

djechlin
  • 59,258
  • 35
  • 162
  • 290
0

No, this is not possible. Like all identifiers in C++, they are no longer available at runtime. Maybe a map or set would be more suitable for your use-case than an enum?

Philipp
  • 67,764
  • 9
  • 118
  • 153
0

Write your own function to handle this...

enum Names {
    Tim     =       0x1,
    Bob     =       0x2,
    Jim     =       0x4
};

std::string GetNameString(int nName)
{
    if( nName == Tim )
        return std::string("Bob");
    else if( nName == Bob )
        return std::string("Tim");
    else if( nName == Jim )
        return std::string("Jim");

    return std::string("");
}
james82345
  • 530
  • 4
  • 13