枚举作为返回字符串的参数

时间:2012-02-02 11:39:24

标签: c++ string enums

我当前的程序使用3种不同的枚举:

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

我想要做的是创建一个全局函数,它接受一个枚举并返回一个字符串(因为枚举的值实际上只是一个总是有值的专用变量名)。 是否可以创建一个采用通用枚举的函数?,例如

string enumToString (enum _enum){}

或者我是否必须为每个不同的枚举创建一个函数?只是一个可能的想法我做了一些阅读,并且一些编译器允许Enum解析为int所以我可以将枚举作为int传递然后使用吗?

4 个答案:

答案 0 :(得分:2)

“ToString-like”函数实现有两种选择:

  1. 实现一个简单的静态开关案例功能。
  2. 代码:

    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. 使用字典查找实现静态函数。
    2. 代码:

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

答案 1 :(得分:2)

这是我主张使用宏来使代码更易理解/可维护(并删除至少一个错误源)的案例之一

因此

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

答案 2 :(得分:1)

不,枚举没有隐含的基类。

您可以使用模板或函数重载。但是,是的,你将不得不手工完成。

枚举→字符串“转换”有一些技巧列出here

答案 3 :(得分:0)

enum名称仅在编译之前才有意义。我不认为有一种便携式或标准定义的方式可以干净利落地完成这项工作。

你可以这样做:

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