次のようなenum
があるとします。
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
このenum
のインスタンスを作成し、それを適切な値で初期化したいので、次のようにします。
Days day = Days.Saturday;
今私は自分の変数またはインスタンスを既存のenum
値でチェックしたいので、私はします:
if (day == Days.Saturday)
{
std::cout<<"Ok its Saturday";
}
これによりコンパイルエラーが発生します。
エラー:「。」トークンの前に主表現が必要です
明確にするために、言うことの違いは何ですか:
if (day == Days.Saturday) //Causes compilation error
そして
if (day == Saturday)
?
この2つは実際には何を表していますか?1つはOKで、もう1つはコンパイルエラーを引き起こしますか?
このコードは間違っています。
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days.Saturday;
if (day == Days.Saturday)
なぜならDays
はスコープでもオブジェクトでもないからです。タイプです。そして型自体はメンバーを持っていません。あなたが書いたのはstd::string.clear
と同等です。 std::string
は型なので、.
を使うことはできません。クラスの instance に.
を使用します。
残念ながら、列挙型は魔法のようなものであり、その類推はそこで止まります。クラスでは、メンバ関数へのポインタを取得するためにstd::string::clear
を実行できますが、C++ 03ではDays::Sunday
は無効です。 (これは悲しいです)。これは、C++がCと(やや)後方互換性があり、Cに名前空間がないため、列挙はグローバル名前空間に含まれる必要があるためです。だから構文は単純です:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday)
幸いなことに、 Mike Seymour は、これがC++ 11で対処されたことを確認しています。 enum
をenum class
に変更すると、独自のスコープを取得します。そのためDays::Sunday
は有効なだけでなく、Sunday
にアクセスするための only の方法です。幸せな日々!
列挙型変数を宣言して比較するにはこれで十分です。
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday) {
std::cout << "Ok its Saturday";
}
これの多くはコンパイルエラーを与えるはずです。
// note the lower case enum keyword
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
これで、Saturday
、Sunday
などを最上位のベア定数として使用でき、Days
を型として使用できます。
Days day = Saturday; // Days.Saturday is an error
同様に後で、テストする:
if (day == Saturday)
// ...
これらのenum
値は裸の定数に似ています-それらはun-scopedです-コンパイラーから少し余分な助けを借りて:(あなたがC++ 11を再使用enumクラス)彼らare n'tカプセル化たとえば、オブジェクトまたは構造体メンバーのように、それらをDays
のmembersとして参照することはできません。
enum class
を導入する C++ 11 を使用すると、探しているものが得られます。
enum class Days
{
SUNDAY,
MONDAY,
// ... etc.
}
// ...
if (day == Days::SUNDAY)
// ...
このC++は、いくつかの点でCとは少し異なります。1つは、変数を宣言するときに、Cがenum
キーワードを使用する必要があることです。
// day declaration in C:
enum Days day = Saturday;
あなたが望むようにスコープを使うためのトリックを使うことができます、ちょうどそのような方法でenumを宣言してください:
struct Days
{
enum type
{
Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday
};
};
Days::type day = Days::Saturday;
if (day == Days::Saturday)
多くのif文を使用するのではなく、enumは文を切り替えるのに適しています。
私は自分のゲーム用に構築しているレベルビルダーでいくつかのenum/switchの組み合わせを使います。
編集:もう一つのこと、私はあなたが似ている構文が欲しいと思う。
if(day == Days.Saturday)
etc
これはC++で実行できます。
if(day == Days::Saturday)
etc
これは非常に簡単な例です。
EnumAppState.h
#ifndef ENUMAPPSTATE_H
#define ENUMAPPSTATE_H
enum eAppState
{
STARTUP,
EDIT,
ZONECREATION,
SHUTDOWN,
NOCHANGE
};
#endif
Somefile.cpp
#include "EnumAppState.h"
eAppState state = eAppState::STARTUP;
switch(state)
{
case STARTUP:
//Do stuff
break;
case EDIT:
//Do stuff
break;
case ZONECREATION:
//Do stuff
break;
case SHUTDOWN:
//Do stuff
break;
case NOCHANGE:
//Do stuff
break;
}
これはC++では機能しません。
Days.Saturday
Daysは、ドット演算子でアクセスできるメンバーを含むスコープまたはオブジェクトではありません。この構文は単なるC#主義であり、C++では無効です。
マイクロソフトは長い間、スコープ演算子を使用して識別子にアクセスできるようにするC++拡張機能を維持してきました。
enum E { A, B, C };
A;
E::B; // works with Microsoft's extension
しかし、これはC++ 11より前の標準ではありません。 C++ 03では、enumで宣言された識別子はenum型自体と同じ有効範囲内にのみ存在します。
A;
E::B; // error in C++03
C++ 11はenum識別子でenum識別子を修飾することを合法にします、そしてまた、それらを周囲のスコープに置く代わりに識別子のための新しいスコープを作成するenumクラスを導入します。
A;
E::B; // legal in C++11
enum class F { A, B, C };
A; // error
F::B;
まだC++ 03を使用していてenumを使用したい場合は、ネームスペース内でenumを使用する必要があります。例えば:
namespace Daysofweek{
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
}
あなたは、名前空間の外で列挙型を使うことができます、
Daysofweek::Days day = Daysofweek::Saturday;
if (day == Daysofweek::Saturday)
{
std::cout<<"Ok its Saturday";
}
厳密に型指定された列挙体 、 C++ 11 standardで利用可能な機能を探しています。列挙型をスコープ値を持つクラスに変換します。
独自のコード例を使用すると、次のようになります。
enum class Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
Days day = Days::Saturday;
if (day == Days::Saturday) {
cout<<" Today is Saturday !"<<endl;
}
//int day2 = Days::Sunday; // error ! invalid
列挙へのアクセサとして::
を使用すると、C++ 11より前のC++標準をターゲットとすると失敗します。しかし、古いコンパイラの中にはそれをサポートしていないものもあり、IDEの中にはこのオプションをオーバーライドして古いC++標準を設定するものもあります。
Gccを使用している場合は、 -std = c ++ 11 または -std = gnu11 を指定してC + 11を有効にします。
幸せになる !
C++のenumは、enum-valuesを宣言するときに、それらが指定した名前でマスクされた整数のようなものです(定義ではなく、動作方法のヒントにすぎません)。
しかし、コードには2つのエラーがあります。
enum
すべて小文字のつづりDays.
は必要ありません。if (day == YourClass::Saturday){}
を使用してください。残念ながら、列挙型の要素は「グローバル」です。あなたはday = Saturday
をすることによってそれらにアクセスします。つまり、enum A { a, b } ;
とenum B { b, a } ;
は矛盾しているからです。
C++(C++ 11を除く)には列挙型がありますが、その中の値はグローバル名前空間に「リーク」されています。
それらをリークさせたくない(そしてenum型を使う必要がない)のであれば、以下を考慮してください。
class EnumName {
public:
static int EnumVal1;
(more definitions)
};
EnumName::EnumVal1 = {value};
if ([your value] == EnumName::EnumVal1) ...
あなたの根本的な問題は.
の代わりに::
を使うことだと思います。
試してください:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days::Saturday;
if(Days::Saturday == day) // I like literals before variables :)
{
std::cout<<"Ok its Saturday";
}