4
#include <iostream>

enum IsOptionAEnum
{
    IsOptionA_YES,
    IsOptionA_NO
};

enum IsOptionBEnum
{
    IsOptionB_YES,
    IsOptionB_NO
};

void TestFunc(IsOptionAEnum optionA, IsOptionBEnum optionB)
{
    if (optionA == IsOptionA_YES || optionA == IsOptionB_YES) // typo
    {
        // ...
    }

    //if (optionA == IsOptionA_YES || optionB == IsOptionB_YES) // correct one
    //{
    //}

}

質問>optionAはタイプIsOptionAEnumであり、の値はありませんIsOptionB_YES。VS2010のコンパイラがこのエラーを検出しないのはなぜですか?

コンパイラがエラーを見つけられない場合、コンパイラがエラーを見つけられるようにこの制限を適用する方法はありますか?

4

3 に答える 3

5

C ++ 11より前の列挙型は、探している型安全性を提供せず、本質的にかなり整数です。

強く型付けされた列挙型クラスが必要です:
http ://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html

于 2013-02-04T16:12:35.800 に答える
5

標準ではこれをエラーにしませんが(列挙型は事実上整数に対する構文です)、これは確かにコンパイラーが検出できるものです。Clangは、でコンパイルすると-Wenum-compare、次のようになります。

Bonsai:~ adamw$ clang++ test.cpp 
    test.cpp:15:45: warning: comparison of two values with different enumeration
      types ('IsOptionAEnum' and 'IsOptionBEnum') [-Wenum-compare]
    if (optionA == IsOptionA_YES || optionA == IsOptionB_YES) // typo
                                    ~~~~~~~ ^  ~~~~~~~~~~~~~

VisualC++はデフォルトでこれについて警告しない可能性があります。コンパイラにフラグを設定してみてください/Wall。これにより、すべての警告が有効になります。それでも警告が表示されない場合は、VCコンパイラチームにリクエストを提出できます。

編集:他の回答やコメントで述べられているように、VC11を使用している場合は、強く型付けされた列挙型を使用できます。

于 2013-02-04T16:13:24.520 に答える
1

非C++11ソリューションは、structsを使用することです。

struct IsOptionAEnum
{
    int val;
    static IsOptionAEnum IsOptionA_YES;
    static IsOptionAEnum IsOptionA_NO;

    IsOptionAEnum( int v ): val(v) {}
};

IsOptionAEnum::IsOptionA_YES(0);
IsOptionAEnum::IsOptionA_YES(1);

if( optionA == IsOptionAEnum::IsOptionA_YES ) // this is type-safe
    // etc.

必要がない場合は、内部値を削除することができます(コピーを無効にし、常に参照を渡し、構造体のアドレスを比較する必要があります)。

C ++ 11では、Prashantが提案したように、型付き列挙型を使用できます。

于 2013-02-04T16:19:37.317 に答える