2017-02-01 9 views
3

厳密に型付けされた列挙型を列挙型の代わりに使用するには、いくつかの良い引数があります。しかし、intへの互換性は、望ましくないリスクの他にも役立ちます。私の場合は、ほとんどがログと比較のために文字列に投げ込みます。強く型付けされたenumのC++変換

enum RiskLevel { None, Warn, Low, High, Critical }; 

void logStuff(RiskLevel rl) { 
    stringstream ss; 
    ss << rl; 
    LOG(s); 
} 

void compareEnum(RiskLevel rl) { 
    if (rl > RiskLevel::Low) { 
     ... 
    } 
} 

私は古い列挙型のこれらの機能がありませんし、おそらく唯一のものではありません。強く型付けされた列挙型を使用しても簡単にログに記録して比較する良い方法は何ですか?

+0

私は強く型付けされた列挙型が何であったか覚えていませんでした – chrise

+0

申し訳ありませんがために列挙型を使用し、実際の例を表すために、それを編集しました。 – Justin

答えて

1

単精度+演算子を定義して整数型に変換します。

enum RiskLevel { None, Warn, Low, High, Critical }; 

auto operator + (RiskLevel value) 
    { return std::underlying_type_t<RiskLevel>(value); } 

void logStuff(RiskLevel rl) { 
    stringstream ss; 
    ss << + rl; 
    LOG(s); 
} 

void compareEnum(RiskLevel rl) { 
    if (+ rl > + RiskLevel::Low) { 
     ... 
    } 
} 

さらに深さはthis answerです。

4

あなたはstd::underlying_typeを使用することができます。

void logStuff(RiskLevel rl) { 
    typedef std::underlying_type<RiskLevel>::type int_type; 
    stringstream ss; 
    ss << int_type(rl); 
    Logger(ss); 
} 
2

あなたは(さらに)あなたにも、より多くの柔軟性を与える、独自のロギングと比較オーバーロードを実現することができます。

std::ostream& operator<<(ostream& os, RiskLevel rl) { 
    os << std::underlying_type<RiskLevel>::type(rl); 
    return os; 
} 

bool operator<(RiskLevel rl1, RiskLevel rl2) { 
    return std::underlying_type<RiskLevel>::type(rl1) < 
       std::underlying_type<RiskLevel>::type(rl2); 
} 

その後、あなたはストリーム挿入を持つことができますオペレータは実際に列挙子の名前を記録します。

+0

これはきちんとしているようですが、すべての列挙型でこれを定義するのは冗長です。好奇心のために、すべてのスコープ付き列挙型のテンプレートだけを書くことは可能でしょうか? – chrise

+1

はい。 ['std :: enable_if'](http://www.cplusplus.com/reference/type_traits/enable_if/)を[' std :: is_enum']と併用することができます(http://www.cplusplus.com/reference/type_traits/is_enum /)。 (強く型付けされた列挙型ではなく、通常の列挙型では_only_を必要とする場合は、[この質問]を参照してください(http://stackoverflow.com/questions/15586163/c11-type-trait-to-differentiate-between-enum-class -and-regular-enum)。 – qxz

2

おそらく、enumクラスのC++ 11を利用するかもしれません。あなたは、あなたの列挙型をどんなタイプにするかを明示的に指定することができます。

enum class Boo : char { 
    START = 'S', 
    END = 'E' 
}; 

enum class Foo : unsigned int { 
    TOP = 1, 
    BOTTOM = 2 
}; 
+0

enumクラスRiskLvlを使ってみました:int {NONE = 0、..}しかし、これは私にエラーをもたらします:std :: basic_ostreamをバインドできません lvalueをstd :: basic_ostream && – chrise

+1

ストリームでそれを使用する場合は、手動で 'static_cast 'を実行する必要があります。そのようなキャストを避けたい場合は、上記のstd :: underlying_typeを使用した回答がベストです(enumクラスで動作します)。 –

関連する問題