通常、次の構文を使用してクラスのキャストを定義できます。
class Test {
public:
explicit operator bool() { return false; }
};
これを行う方法はありますか、enum class
?
いいえ、ちがいます。
実際には、enum class
はまったくクラスではありません。 class
キーワードが使用されるのは、スコープ外のenum
をスコープ付きenum
に突然変更すると、コードを再処理するall enumsコードが必要になるためです。したがって、委員会は、新しいスタイルの列挙と古いスタイルの列挙を区別するために、新しいキーワードにclass
のタグを付けることを決定しました。これは、キーワードであるため、enum
にclass
C++で。彼らは別のものを選んだかもしれませんが、それはとにかくはるかに意味がありませんでした。
ただし、class
キーワードにもかかわらず、それらは通常の列挙型であり、列挙子(およびそれらに割り当てられている可能性のある値)のみが角かっこ内で許可されます。
いいえ。ただし、constexpr
メンバーとコンストラクターを使用して、通常のクラス型を列挙型クラスのように機能させることができます。そして、必要なすべての追加メンバー関数を追加できます。
switch
でも機能することの証明:
#include <iostream>
struct FakeEnum
{
int x;
constexpr FakeEnum(int y = 0) : x(y) {}
constexpr operator int() const { return x; }
static const FakeEnum A, B, Z;
};
constexpr const FakeEnum FakeEnum::A{1}, FakeEnum::B{2}, FakeEnum::Z{26};
std::istream& operator>>(std::istream& st, FakeEnum& fe)
{
int val;
st >> val;
fe = FakeEnum{val};
return st;
}
int main()
{
std::cout << "Hello, world!\n";
FakeEnum fe;
std::cin >> fe;
switch (fe)
{
case FakeEnum::A:
std::cout << "A\n";
break;
case FakeEnum::B:
std::cout << "B\n";
break;
case FakeEnum::Z:
std::cout << "Z\n";
break;
}
}
switch
を使用する場合、int
との暗黙的な相互変換が不要であることの証明:
#include <iostream>
/* pseudo-enum compatible with switch and not implicitly convertible to integral type */
struct FakeEnum
{
enum class Values { A = 1, B = 2, Z = 26 };
Values x;
explicit constexpr FakeEnum(int y = 0) : FakeEnum{static_cast<Values>(y)} {}
constexpr FakeEnum(Values y) : x(y) {}
constexpr operator Values() const { return x; }
explicit constexpr operator bool() const { return x == Values::Z; }
static const FakeEnum A, B, Z;
};
constexpr const FakeEnum FakeEnum::A{Values::A}, FakeEnum::B{Values::B}, FakeEnum::Z{Values::Z};
std::istream& operator>>(std::istream& st, FakeEnum& fe)
{
int val;
st >> val;
fe = FakeEnum(val);
return st;
}
int main()
{
std::cout << "Hello, world!\n";
FakeEnum fe;
std::cin >> fe;
switch (fe)
{
case FakeEnum::A:
std::cout << "A\n";
break;
case FakeEnum::B:
std::cout << "B\n";
break;
case FakeEnum::Z:
std::cout << "Z\n";
break;
}
// THIS ERRORS: int z = fe;
}
C++では非メンバーキャスト演算子を定義できません。また、列挙型のメンバー関数を定義することはできません。したがって、キャスト演算子を実装するのと同じ方法で、列挙型を他の型に変換する無料の関数を実行することをお勧めします。
例えば.
bool TestToBool(enum_e val)
{
return false;
}
const char *TestToString(enum_e val)
{
return "false";
}
これらの列挙型をブール値に関連付けるには、2つのファイル.hと.cppに分割する必要があります。ここにそれが役立つかどうかです:
enum.h
///////////////////////////////
// enum.h
#ifdef CPP_FILE
#define ENUMBOOL_ENTRY(A, B) { (enum_e) A, (bool) B },
struct EnumBool
{
enum_e enumVal;
bool boolVal;
};
#else
#define ENUMBOOL_ENTRY(A, B) A,
#endif
#ifdef CPP_FILE
static EnumBool enumBoolTable[] = {
#else
enum enum_e
{
#endif
ENUMBOOL_ENTRY(ItemA, true),
ENUMBOOL_ENTRY(ItemB, false),
...
};
bool EnumToBool(enum_e val);
enum.cpp
///////////////////////////////
// enum.cpp
#define CPP_FILE
#include "enum.h"
bool EnumToBool(enum_e val)
//implement
私はそれをコンパイルしなかったので、何かエラーがあればそれを簡単にしてください:)。