2015-12-16 14 views
5

には、次のC++列挙を考えるコンパイラ列挙再宣言の競合を解決する:どのよう

enum Identity 
{ 
    UNKNOWN = 1, 
    CHECKED = 2, 
    UNCHECKED = 3 
}; 

enum Status 
{ 
    UNKNOWN = 0, 
    PENDING = 1, 
    APPROVED = 2, 
    UNAPPROVED = 3 
}; 

ザ・コンパイラは、両方のUNKNOWNアイテムを矛盾と、このエラーがスローされました:

error: redeclaration of 'UNKNOWN'

私は1つを変更し、このエラーを解決することができていますUNKNOWNUNKNOWN_aの名前を変更する必要はありません。

この競合を解決するにはどうすればいいですか?enumアイテム名を変更せずにを解決するにはどうすればよいですか?

答えて

11

これにはscoped enumerationsを使用できます。これには、C++ 11以上のサポートが必要です。

enum class Identity 
{ 
     UNKNOWN = 1, 
     CHECKED = 2, 
     UNCHECKED =3 
}; 

enum class Status 
{ 
     UNKNOWN = 0, 
     PENDING = 1, 
     APPROVED = 2, 
     UNAPPROVED =3 
}; 

int main() 
{ 
    Identity::UNKNOWN; 
    Status::UNKNOW; 
} 

Live Example

4

スコープの使用enum(C++ 11) - enum class es。彼らは重複名で外側の範囲を汚染しません。

ただし、スコープ解決演算子 - Identity::UNKNOWNではなく、)の列挙値にアクセスする必要があります。

3

C++ 11を使用して(それは本当に今では、私が意味する、それはすでに2015年だはずです)実行可能ではない場合は、名前空間を使用することを検討してください:

namespace Identity { 
enum { 
     UNKNOWN = 1, 
     CHECKED = 2, 
     UNCHECKED =3 
}; 
} 

namespace Status { 
enum { 
     UNKNOWN = 0, 
     PENDING = 1, 
     APPROVED = 2, 
     UNAPPROVED =3 
}; 
} 

しかし、 、実際にはenum classがはるかに優れています。

+0

パラメータとして使用する場合は、そのまま動作しません。 – chris

+0

@chris私は認識しています。これは単純に 'enum class'を使用しない場合の問題の1つです。つまり、列挙型を名前( 'enum value {/*...*/')で宣言して 'void foo(Identity :: value)'のように使うことはできますが、型の利点は失われます安全性など。 –

+0

まあ、面白いことに、C++ 11は特に商業領域では一般的に実行可能ではありません。たとえば、私が働く会社の多くの顧客がRHELのような古いシステムを使い続けていて、システムが正常に実行されている間はアップグレードする必要があります(リリースアップグレード中に重大な非互換性が発生するのはかなり一般的です)。その結果、C++ 11は禁止されており、すべてが古いコンパイラで構築されなければなりません。事実、私が働いた最後の4社のすべてでC++ 11が禁止されました。私が以前に働いた会社の1つはAFAIKもまだMSVC 6でビルドしています:-) – axalis

2

これは、(私は、文字列に列挙名の自動変換、シリアライズ/デシリアライゼーションのなどのような、もっと派手な何かを必要としない場合)、私は通常、列挙型を宣言する方法を次のとおりです。

struct Identities 
{ 
    enum Type 
    { 
     UNKNOWN = 1, 
     CHECKED = 2, 
     UNCHECKED = 3 
    }; 
}; 

typedef Identities::Type Identity; 

struct States 
{ 
    enum Type 
    { 
     UNKNOWN = 0, 
     PENDING = 1, 
     APPROVED = 2, 
     UNAPPROVED = 3 
    }; 
}; 

typedef States::Type Status; 

// usage 
Identity identity = Identities::UNKNOWN; 
Status status = States::UNKNOWN; 

作品ですべてのC++バージョンであり、タイプセーフでもあります。構造体の代わりに名前空間を使うこともできます(しかし、私は通常構造体を使います)。