2012-01-03 13 views
1

次のようないくつかの入れ子になった列挙型があります。私は、isValid()関数をenum定義に可能な限り近いものとして定義したいと考えています。実際のコードは、ネストされた名前空間と構造体の複数のレベルでより冗長です。入れ子になった列挙体のC++操作

struct S 
{ 
    enum E { V1, V2 }; 
    /* ????? */ bool isValid(E e) { return e==V1 || e==V2; } 
}; 

template <typename Enum> 
bool legalValue(Enum e) 
{ 
    return isValid(e); 
} 

グローバル名前空間にisValid()を配置することなく、このコードを動作させるために、それは可能ですか?

isValid()が優れているかどうかについてはお答えください。この質問は、operator<<()をオーバーライドして、意味のある列挙値をストリームできるようにするためのものと同じです。その場合、operator<<()のエッセンスはstruct Sの体内にある方法はありますか?

+1

ここで何が問題なのかわかりません。 'isValid()'関数を 'static'にし、' legalValue() '関数を' return S :: isValid(e); 'に変更してください。これはコンパイルすべきだと思います... –

+0

アイデアは'legalValue ()'は関連する 'isValid()'関数を持つ 'enum'に対して動作するはずです。 'class'や' struct'でネストされた列挙型では機能しません。 – paperjam

+0

構造体ではなく、名前空間内に列挙型を入れてみてください。このように、ADLは(私はそれをテストしていない)キックする必要があります、あなたはenumが宣言されている名前空間に関係なくisValidを呼び出すことができるはずです。 – paercebal

答えて

4

いいえ、からisValidを移動する必要があります。しかし、enumの定義はその内部にとどまることができます。

struct S 
{ 
    enum E { V1, V2 }; 
}; 

bool isValid(S::E e) { return e == S::V1 || e == S::V2; } 

template <typename Enum> 
bool legalValue(Enum e) 
{ 
    return isValid(e); 
} 
+0

OPの規定の1つは、 "グローバル名前空間にisValid()を置かなくてもこのコードを動作させることは可能ですか?" ... –

+0

ありがとうございます、しかし、これ以外の解決策があるかどうか尋ねていました。 – paperjam

+1

@OliCharlesworth:答えはノーだと思います。答えを更新しましたが、標準からコーラスと詩を引用することはできません。 –

3

SS::Eから見つけることができません。

Sが名前空間であれば、Koenig lookupは、それがグローバル名前空間の一部でない場合でも、isValidを見つけるだろうが、私はそれはあなたが何を意味するかではないと思います。

1

これは、標準C++のために、すなわちC++ 2011のために、あなたが前方にネストされた列挙宣言している場合:もちろん

struct S { enum E: int; }; 

enum S::E: int { V1, V2 }; 
bool isValid(S::E e) { return e == S::V1 || S::V2; } 

を、あなたはまたに巣に列挙を必要はありません囲みスコープの汚染を避けるために、構造体:代わりにあなたが違法になるV1またはV2非修飾を使用して

enum class S { V1, V2 }; 
bool isValid(S e) { return e == S::V1 || S::V2; } 

を使用すると思います。

1

これらは技術的な点ですが、isValidをグローバルにする別のオプションは、legalValueを過負荷にする(または特化する)ことです。

struct S 
{ 
    enum E { V1, V2 }; 
    static bool isValid(E e) { return e==V1 || e==V2; } 
}; 
bool legalValue(S::E e) { return S::isValid(e); } 

template <typename Enum> 
bool legalValue(Enum e) { return isValid(e); } 

別のオプションは、isValidグローバル友人を作ることです。これは、それがほとんど全面的に自由なグローバル関数であることとは全く異なります。

struct S 
{ 
    enum E { V1, V2 }; 
    friend bool isValid(E e) { return e==V1 || e==V2; } 
}; 
template <typename Enum> 
bool legalValue(Enum e) { return isValid(e); } 
関連する問題