2012-02-02 21 views
3

私の現在のプログラムは、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として渡してからそれを使うことができますか?

+0

それでは、あなたがやりたいことは、文字列に列挙値を変換するのですか?たぶんあなたは質問のタイトルを修正する必要があります... – tenfour

+0

'enumの値は実際には常に値 'whutを持つ特殊な変数名です –

+0

コンパイラがenumを読むときに@Lightness Ex {this、thisTo}; (具体的に設定されていない限り)それらの値を生成しますが、それらにアクセスするには、クラス内の正確なメソッドに到達するために解決演算子を使用するようなその値を表す名前を使用する必要があります。 Enumは特定の値(intアドレス)に解決されますが、その値がわかっていても逆変換は決して解決しません。 " – gardian06

答えて

2

「ToStringメソッドのような」関数の実装の2つのオプションがあります。

  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

私はオプション1が好きです。ちょうどもっときれいに見えます。 – gardian06

+0

個人的には、いくつかの列挙定数がある場合は最初のものを選択します。逆に、2番目の列挙定数は、多くの列挙定数がある場合は実際です。 –

0

enumコンパイルする前に名前が意味を成します。私は、これをきれいなやり方で行うためのポータブルまたは標準的な方法はないと思います。次のように

あなたはそれを行うことができます:

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

基本的に私は関数に列挙を取得することができますし、私は基本的に右の文字列を返すケーススイッチのように行うことができます。私は必ずしも自分の名前を返す必要はありませんが、少なくとも論理チェックを行っています。 – gardian06

+0

@ gardian06はい、私の編集のようですが、それは一般的ではありません(とにかく意味をなさないでしょう)。あなたはたくさんのものをハードコードしなければなりません。とにかくこれはなぜ必要でしょうか? –

+0

を使用してログメッセージを生成します。なぜなら、私はこれらの上に物事を統合する必要があり、 "メソッドは返しました:6"はデバッグのために "メソッドが返された:Error2"ほど意味がありません。 – gardian06

1

はありません、列挙型は暗黙の基底クラスを持っていません。

テンプレートを使用したり、関数のオーバーロードを使用することができます。しかし、はい、あなたは手でそれをしなければならないでしょう。

enum →の文字列「変換」がhereと記載されています。

2

これは私が保守性/あなたのコードがよりわかりやすい作り(およびエラーの少なくとも1つのソースを削除)するために、マクロを使用することを提唱したいような場合の一つである

したがって

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