84

私は C++ プログラミングの初心者です。

今日、私は新しいトピックに出くわしました: 強く型付けされたenum. 私はそれを少し調べましたが、今までなぜこれが必要なのか、同じものを何に使うのかわかりません。

たとえば、次の場合:

enum xyz{a, b, c};
/*a = 0, b = 1, c = 2, (Typical C format)*/

なぜ私たちは書く必要があるのですか:

enum class xyz{a, b, c};

ここで何をしようとしていますか?私の最も重要な疑問は、それをどのように使用するかです。少し例を挙げていただければ、理解できます。

4

5 に答える 5

116

OK、最初の例:古いスタイルの列挙型には独自のスコープがありません:

enum Animals {Bear, Cat, Chicken};
enum Birds {Eagle, Duck, Chicken}; // error! Chicken has already been declared!

enum class Fruits { Apple, Pear, Orange };
enum class Colours { Blue, White, Orange }; // no problem!

次に、それらは暗黙的に整数型に変換され、奇妙な動作につながる可能性があります。

bool b = Bear && Duck; // what?

最後に、C++11列挙型の基になる整数型を指定できます。

enum class Foo : char { A, B, C};

以前は、基になるタイプが指定されていなかったため、プラットフォーム間の互換性の問題が発生する可能性がありました。編集コメントでは、C++11で「古いスタイル」の列挙型の基になる積分型を指定することもできることが指摘されています。

于 2012-09-25T10:34:47.003 に答える
17

この IBM ページには、列挙型に関する優れた記事があります。非常に詳細でよく書かれています。ここでは、いくつかの重要なポイントを簡単に説明します。

スコープ付き列挙型は、通常の列挙型によって発生する制限のほとんどを解決します: 完全なタイプ セーフ、適切に定義された基になる型、スコープの問題、前方宣言。

  • スコープ付き列挙型から他の型への暗黙的な変換をすべて禁止することで、型の安全性を確保します。
  • 新しいスコープを取得すると、enum は囲んでいるスコープに含まれなくなり、名前の競合が回避されます。
  • スコープ付き列挙型を使用すると、列挙の基になる型を指定できます。スコープ付き列挙型の場合、指定しない場合はデフォルトで int になります。
  • 基になる型が固定されているすべての列挙型を前方宣言できます。
于 2012-09-25T10:35:04.943 に答える
11

の値は、C列挙型ではなく、enum class実際には型です。enum classunderlying_type

enum xyz { a, b, c};
enum class xyz_c { d, f, e };

void f(xyz x)
{
}

void f_c(xyz_c x)
{
}

// OK.
f(0);
// OK for C++03 and C++11.
f(a);
// OK with C++11.
f(xyz::a);
// ERROR.
f_c(0);
// OK.
f_c(xyz_c::d);
于 2012-09-25T10:33:38.080 に答える
3

列挙スコープ

列挙は、その列挙子を周囲のスコープにエクスポートします。これには 2 つの欠点があります。まず、同じスコープで宣言された異なる列挙型の 2 つの列挙子が同じ名前を持つ場合、名前の競合が発生する可能性があります。第二に、列挙名を含む完全修飾名を持つ列挙子を使用することはできません。

enum ESet {a0, a, a1, b1, c3};
enum EAlpha{a, b, c}

select = ESet::a; // error
select = a;       // is ambigious
于 2012-09-25T10:36:10.187 に答える