enum как аргумент, возвращающий строку - PullRequest
3 голосов
/ 02 февраля 2012

Моя текущая программа использует 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, поэтому я могу передать enum как int и затем работать с ним?

Ответы [ 4 ]

2 голосов
/ 02 февраля 2012

Это один из тех случаев, когда я рекомендовал бы использовать макросы, чтобы сделать ваш код более понятным / обслуживаемым (и устранить хотя бы один источник ошибок)

Таким образом

  #define TOSTRING(name) case name: return #name
  switch (val)
  {
      TOSTRING(Thing1);
      TOSTRING(Thing2);
      default:
         //bad things happened.
   }
2 голосов
/ 02 февраля 2012

Существует два варианта реализации функции типа ToString:

  1. Реализация простой статической функции переключения.

Код:

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. Реализация статической функции с поиском в словаре.

Код:

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 голос
/ 02 февраля 2012

Нет, перечисления не имеют неявного базового класса.

Вы можете использовать шаблоны или перегрузку функций.Но, да, вам придется сделать это вручную.

Есть несколько хитростей для перечисления enum → string «преобразование» здесь .

0 голосов
/ 02 февраля 2012

enum имена имеют смысл только перед компиляцией. Я не думаю, что есть портативный или стандартный способ сделать это чистым способом.

Вы можете сделать это следующим образом:

std::string getName(ThingEnum x)
{
   switch (x)
   {
   case Thing1:
      return "Thing1";
   case Thing2:
      return "Thing2";
   //....
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...