3

My current program uses 3 different enums:

enum ThingEnum{
    Thing1 = 0,
    Thing2 = 1,
    Thing3 = 2,
    OtherThing = 3
};
enum ReturnEnum {
    Success = 4,// the method did what it is supposed to
    Error1 = 5,// an error occured
    Error2 = 6,// an error occured
    Error3 = 7,// an error occured
    Error4 = 8,// a fatal error occured program must terminate
    Pointer = 9// the method may need to be called again
};
enum TypeEnum {
    Type1 = 10,
    Type2 = 11,
    Type3 = 12,
    Type4 = 13,
    OtherType = 14
};  

What I want to do is create a global function that takes an enum and returns a string (as the value of an enum is really just a specialized variable name that always has a value). Is it possible to create a function that takes a generic enum? e.g.

string enumToString (enum _enum){}

or would I have to make a function for each different enum? Just a possible thought I did some reading, and some compilers allow for a Enum to resolve to an int so could I pass the enum as an int and then work with it?

6
  • So what you want to do is convert an enum value to a string? Maybe you should revise the question title... Commented Feb 2, 2012 at 11:41
  • as the value of an enum is really just a specialized variable name that always has a value whut Commented Feb 2, 2012 at 11:52
  • @Lightness when the compiler reads enum Ex{this, thisTo}; it will generate values for them (unless they are set to specifics), but to access them you need to use the name representing that value as kind of like using a resolution operator to get to an exact method in a class. as literature on enums will state "an Enum will resolve to a specific value (an int address), but even if that value is known the reverse conversion will never resolve" Commented Feb 2, 2012 at 12:18
  • 1
    @gardian06: Yes, I know what enums are, thanks. I was wondering what on earth the quoted passage was supposed to mean. Commented Feb 2, 2012 at 14:01
  • @LightnessRacesinOrbit it means that you can use an enum the same that in C you could use #define CONST_THING = 0x0A and every time you use CONST_THING it will always resolve to that value. the same way that enum Ex{this, thisTo} every time you use thisTo it will always resolve to the value assigned to it (assuming scope) hens Ex is a specialized variable, and thisTo is its value. yes the better statement probably should have been "as an enum is really just a specialized variable that has preset known values" Commented Feb 3, 2012 at 0:56

4 Answers 4

2

There are two options of "ToString-like" function implementation:

  1. Implement a simple static switch-case function.

Code:

std::string ThingEnumToString(ThingEnum thing)
{
    switch (thing) {
    case Thing1:
        return std::string("Thing1");
    case Thing2:    
        return std::string("Thing2");
    case Thing3:
        return std::string("Thing3");        
    case OtherThing:
        return std::string("OtherThing");
    default:
        throw std::invalid_argument("thing");
        break;
    }
}
  1. Implement a static function with a dictionary lookup.

Code:

typedef std::map<ThingEnum, std::string> ThingsMap;

static ThingsMap GetThingsMap()
{
    ThingsMap things_map;
    things_map.insert(ThingsMap::value_type(Thing1, std::string("Thing1")));
    things_map.insert(ThingsMap::value_type(Thing2, std::string("Thing2")));
    things_map.insert(ThingsMap::value_type(Thing3, std::string("Thing3")));
    things_map.insert(ThingsMap::value_type(OtherThing, std::string("OtherThing")));
    return things_map;
}

static std::string ThingEnumToString(ThingEnum thing)
{
    static const ThingsMap things(GetThingsMap());
    ThingsMap::const_iterator it = things.find(thing);
    if (it != things.end()) {
        return it->second;
    } else {
        throw std::invalid_argument("thing");
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Personally, I choose the first one when there a few enumeration constants. On the contrary, the second one is actual when there is a lot of enumeration constants.
2

This is one of those cases where I'd advocate the use of macros to make your code more intelligible / maintainable (and remove at least one source of errors)

Thus

  #define TOSTRING(name) case name: return #name
  switch (val)
  {
      TOSTRING(Thing1);
      TOSTRING(Thing2);
      default:
         //bad things happened.
   }

Comments

1

No, enums have no implicit base class.

You can use templates, or function overloading. But, yes, you're going to have to do it by hand.

There are some tricks for enum→string "conversion" listed here.

Comments

0

enum names only make sense before compilation. I don't think there's a portable or standard-defined way of doing this in a clean fashion.

You could do it as follows:

std::string getName(ThingEnum x)
{
   switch (x)
   {
   case Thing1:
      return "Thing1";
   case Thing2:
      return "Thing2";
   //....
   }
}

3 Comments

basically if I can get the enum into the function then I can basically do like a case switch to return the right string. I don't necessarily want to have it return its own name, but at least have a logic check done on it.
@gardian06 yes, like in my edit, but it's not generic(which wouldn't make sense anyway) and you have to hardcode a lot of stuff. Why would you need this anyway?
to generate log messages. because I will have to be integrating stuff on top of these, and "method returned: 6" is not as meaningful as "method returned: Error2" for debugging.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.