2011-02-10 31 views
4

これは私が何をしたいです:列挙型は

enum MyEnum 
{ 
    ONE = 1, TWO, THREE 
}; 

template<class T> 
void func() 
{ 
    cout << T::TWO << endl; 
} 

int main() 
{ 
    func<MyEnum>(); 
}; 

それは動作しますが、私は警告が出ます:「C4482警告:非標準の拡張機能を使用:修飾名に使われる列挙 『MyEnum』」

警告を表示せずにこれを行うにはどうすればいいですか

+1

'enum E1 {ONE、TWO}; enum E2 {ONE、TWO};期待通りに 'ONE'という矛盾した宣言を与えます。' enum E1'の値は名前空間 'E1'に入りません。あなたは何を期待していますか? – delnan

+1

'TWO'は' MyEnum'で定義されています。これはあなたが示したクラスや名前空間の一部ではありません。 enumはスコープを宣言していないため、スコープ演算子を使用して解決しません。 –

+0

これは私がしたいことです、私はそれを印刷するときにE1とE2の両方を渡して別の値を得ることができるようにしたいです – hidayat

答えて

5

列挙型はここでややこしいです。 1つの型と2つの型は外側の名前空間にあります。 名前に型を追加すると警告が表示されます。 TWOは、外側の名前空間で知られているので あなただけの修飾子

template<class T> 
void func() 
{ 
    cout << TWO << endl; 
} 

を削除することができます。 また、enumを囲む構造体に移動することもできます。

struct EnumContainer 
{ 
    enum MyEnum 
    { 
     ONE = 1, TWO, THREE 
    }; 
}; 

template<class T> 
void func() 
{ 
    std::cout << T::TWO << std::endl; 
} 

int main() 
{ 
    func<EnumContainer>(); 
}; 

コンパイラは正しく動作するはずです。

+0

で、「linuxとosx」と表示されているG ++コンパイラのほとんどがエラーになります。「タイプ1と2は外部名前空間にあります。" - タイプではなく、Standardeseでは* enumerators * :-)。 –

+2

はC++で' enum struct MyEnum {ONE、TWO}; '、http://en.wikipedia.org/wiki/C%2Bを参照してください。 %2B0x#Strongly_typed_enumerations –

1

テンプレートパラメータとしてenumを使い、それを書いたときに個々の列挙型を別々に認識するのはいいですが、それは起こりません。代わりに、私はあなたが次のことを宣言することを示唆している可能性があります

template<MyEnum T> 
void func(){ 
    std::cout << T << std::endl; 
} 

C++の素晴らしいところは、テンプレートが構成されている方法はあなたに目を向けると、完全なシステムを提供することです。したがって、個々のenum値を取得すると宣言したように、このような別の呼び出しは必要ありません。必要なときに必要なときにのみの値ごとに別々の関数を作成することができます。

ここで@delnanがコメントしたように、同じ名前の2つの異なるEnumを持つことはできません。支援を期待

struct Foo{ 
    int TWO; 
}; 

struct Bar{ 
    int TWO; 
}; 

template<typename T> 
void func(){ 
    std::cout << T::TWO << std::endl; 
} 

:あなたは、しかし、 TWOがそのようなことと呼ばれるメンバ変数を持つクラスを持つことができます。

+0

また、enumを構造体のメンバーとして宣言することもできます(異なるスコープで複数の列挙型を定義できるようになります)。 –

+0

このコンパイルは疑問です。 'typename'は型に使用され、' TWO'はクラスのインスタンスを必要とする属性です。 –

+0

@Mathieu M.あなたは正しく、変更されました。 – wheaties

1

列挙型(プレC++ 0x)は整数型のように扱われます。

実際、表記MyEnum :: TWOはガベージです。クラスまたは名前空間MyEnumはありません。 ONE、TWO、およびTHREEの名前は、enumが定義されている名前空間(この場合はグローバル名前空間)に持ち込まれます。

TWO is not a member of MyEnumのようなエラーが発生するはずです。

動作をエミュレートする1​​つの方法は、他の人が示唆しているように、それを構造体またはクラスに配置することです。