2013-06-13 20 views
5

Mam kawałek kodu, całkiem podobny do tego:Bind char do typu enum

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

Teraz wyobraź sobie, mam znacznie więcej typów enum i ich nazwy są już .... dobrze co ja dostać nie jest to bardzo dobry kod patrząc i zastanawiałem się, czy to możliwe, aby powiązać konkretny char do typu enum i może zrobić coś takiego:

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

lub jakiejkolwiek innej metody, które mogłyby uczynić ten kod „ładniejszy”. Czy to możliwe?

+0

Można zawsze mają 'std :: map ', ale nie jestem pewien, że kod byłby czysty z tak małym zestawem wartości. Przynajmniej można zamknąć konwersję wewnątrz funkcji, dzięki czemu można jej ponownie użyć. – cdhowie

+2

"Std :: map" wydaje się tu przesadzony, wystarczy prosty zbiór: 'cout <<" SME "[Full [i]]'. (To wciąż wymaga ulepszeń w zakresie możliwości zarządzania i bezpieczeństwa.) – hvd

+0

Może to być również przypadek dla nagłówka #define. #define START 'S' ... –

Odpowiedz

9

Niestety, niewiele można zrobić, aby to posprzątać. Jeśli masz dostęp do C++ 11 silnie wpisany funkcji enumeratora, a następnie można zrobić coś jak następuje:

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

A potem można zrobić coś takiego:

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

Jednakże, jeśli nie mają dostępu do tej funkcji wtedy tam nie wiele można zrobić, moja rada byłoby mieć zarówno globalną mapę std::map<Section, char>, który dotyczy każdej sekcji enum do charakteru lub funkcji pomocnika z prototypem:

inline char SectionToChar(Section section); 

który właśnie wdraża oświadczenie switch() w bardziej przystępny sposób, np:

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

Pierwsze rozwiązanie wydaje się świetne, niestety nie mam do niego dostępu. – petric

+0

Myślę, że potrzebujesz "case Section :: START:" itd.? – aschepler

+0

@aschepler Nie, nie musisz określać zakresu nieistniejącego globalnego 'enum'. –

5

W takiej sytuacji może to być trudne i oddać swoje znaki.

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

... 

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

Wygląda na to, że działa poprawnie, ale czy jest "legalny"? Mam na myśli, czy to jest dobre programowanie? – petric

+1

Czy to jest zgodne z prawem, tak. Czy to dobre programowanie ... cóż, nie wiedząc dokładnie, co próbujesz osiągnąć, nie mogę na to odpowiedzieć. Jest jednak ładniejsza. –

0

Myślę, że najlepszym rozwiązaniem w tym przypadku byłoby użyć mapy:

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