2013-06-13 5 views
5

У меня есть кусок кода, довольно похожее на это:Bind полукокса к перечислимому типу

class someclass 
{ 
public: 
enum Section{START,MID,END}; 
vector<Section> Full; 
void ex(){ 
    for(int i=0;i<Full.size();i++) 
    { 
     switch (Full[i]) 
     { 
     case START : 
        cout<<"S"; 
        break; 
     case MID : 
        cout<<"M"; 
        break; 
     case END: 
      cout<<"E"; 
      break; 
     } 
    } 
    } 
}; 

Теперь представьте, у меня есть гораздо больше типов перечислений и их имена больше .... хорошо, что я получаю это не очень хорошо выглядит код и мне было интересно, если это возможно, чтобы связать конкретный символ к типу перечислений и, возможно, сделать что-то вроде этого:

for(int i=0;i<Full.size();i++) 
    { 
     cout<(Full[i]).MyChar(); 
    } 

или любой другой метод, который мог бы сделать этот код «симпатичнее». Возможно ли это?

+0

Вы всегда можете иметь 'зОго :: Карты ', но я не убедитесь, что код окажется более чистым с таким небольшим набором значений. По крайней мере, вы можете инкапсулировать преобразование внутри функции, чтобы ее можно было повторно использовать. – cdhowie

+2

«std :: map» кажется излишним, достаточно простого массива: 'cout <<" SME "[Full [i]]'. (Это все еще нуждается в улучшениях для управляемости и безопасности.) – hvd

+0

Может быть также и для заголовка #define. #define START 'S' ... –

ответ

9

К сожалению, вы не можете сделать это, чтобы очистить это. Если у вас есть доступ к C++ 11 сильно типизированных функция перечислителей, то вы могли бы сделать что-то вроде следующего:

enum class Section : char { 
    START = 'S', 
    MID = 'M', 
    END = 'E', 
}; 

И тогда вы могли бы сделать что-то вроде:

std::cout << static_cast<char>(Full[i]) << std::endl; 

Однако, если вы не имеют доступа к этой функции, то есть не так много вы можете сделать, мой совет будет иметь либо глобальную карту std::map<Section, char>, которая связывает каждый enum секцию к персонажу, или вспомогательную функцию с прототипом:

inline char SectionToChar(Section section); 

Который только реализует switch() заявление в более доступной форме, например:

inline char SectionToChar(Section section) { 
    switch(section) 
    { 
    default: 
     { 
      throw std::invalid_argument("Invalid Section value"); 
      break; 
     } 
    case START: 
     { 
      return 'S'; 
      break; 
     } 
    case MID: 
     { 
      return 'M'; 
      break; 
     } 
    case END: 
     { 
      return 'E'; 
      break; 
     } 
    } 
} 
+0

Первое решение кажется отличным, к сожалению, у меня нет доступа к нему. – petric

+0

Я думаю, вам нужен раздел case :: START: 'и т. Д.? – aschepler

+0

@aschepler Нет, вам не нужно квалифицировать область не строго типизированного глобального 'enum'. –

5

В такой ситуации вы могли бы быть хитрым и бросить свои символы.

enum Section{ 
    START = (int)'S', 
    MID = (int)'M', 
    END = (int)'E' 
}; 

... 

inline char getChar(Section section) 
{ 
    return (char)section; 
} 
+0

Ну, похоже, это сработает, но разве это «законно»? Я имею в виду, он считается хорошим программированием? – petric

+1

Это законно, да. Это хорошее программирование ... ну, не зная точно, что вы пытаетесь выполнить, я не могу ответить на это. Тем не менее, это красивее. –

0

Я думаю, что лучшее решение в этом случае будет использовать карту:

#include <iostream> 
#include <map> 
class someclass 
{ 
    public: 
    enum Section{START = 0,MID,END}; 
    map<Section,string> Full; 

    // set using Full[START] = "S", etc 

    void ex(){ 
     for(int i=0;i<Full.size();i++) 
     { 
      cout << Full[i]; 
     } 
    } 
}; 
Смежные вопросы