他の場所で指摘されているように、問題は名前空間とは関係ありませんが|
、intを作成するために使用し、その値を.を期待する関数に渡そうとすることと関係がありenum
ます。問題を「捨てる」場合でも、型であると主張する変数に不一致な値が含まれることになりますFeeling::e
。
多くの場合、enum
メンバーが自然な順序で連続した値を取得できるようにする方が便利です。これにより、メンバーをインデックス値として簡単に使用できるようになり、コンパイラーは、メンバーを計算されたgotoに使用するswitchステートメントを最適化するための機能を備えていることがよくあります。enum
ただし、メンバーのコレクションをセットのように渡す必要がある場合がよくあります。
enum
これは、をフラグ値に変換するために使用するヘルパーの簡略化されたバージョンです。enum
これは、すでに順次定義されているが、それらのコレクションをセットとして表現したいコードに特に役立ちます。まず、それがどのように使用されるかの例(そして、ビット演算の結果をenum
型にキャストするソリューションが、同様の結果を達成するために奇妙なことをしなければならないことに注意してください)。
namespace Feeling {
enum e { Happy, Sad, Blue, Angry, Mad, MAX_e };
std::string estr[] = { "Happy", "Sad", "Blue", "Angry", "Mad" };
}
void HowDoYouFeel (const Flags<Feeling::e> &feelings)
{
for (int i = 0; i < Feeling::Max_e; ++i) {
if (feelings.has(i)) std::cout << Feeling::estr[i] << std::endl;
}
if (feelings.has(Feeling::Angry)) {
std::cout << "The Hulk is in the house." << std::endl;
}
}
HowDoYouFeel(Feeling::Happy | Feeling::Blue | Feeling::Mad);
これは、演算子のオーバーロード、テンプレート、およびヘルパーテンプレートを使用して実現されます。コードがインライン化されているため、最適化が有効になっている実際の実行時オーバーヘッドは低く、enum
定数のシフト演算はコンパイル時に計算されます。
template <typename E>
class Flags
{
unsigned long long m_opts;
public:
Flags () : m_opts(0) {}
Flags (E e) : m_opts(1ULL << e) {}
Flags (const FlagsTmp<E> &ot) : m_opts(ot.m_opts) {}
bool has (unsigned i) const { return m_opts & (1ULL << i); }
bool has (E e) const { return m_opts & (1ULL << e); }
};
Flags
テンプレートは、型をテンプレートパラメータとして受け取り、enum
初期化するためのいくつかの簡単な方法を提供します。このhas
メソッドはenum
、が設定されたフラグの1つであるかどうかを確認するために使用されます。
template <typename E>
class FlagsTmp
{
friend class Flags<E>;
mutable unsigned long long m_opts;
public:
FlagsTmp (E e) : m_opts(1ULL << e) {}
const FlagsTmp & operator | (E e) const {
m_opts |= (1ULL << e);
return *this;
}
};
FlagsTmp
すべてのフラグを収集するための仲介として使用されます。|
これにより、フラグを操作と一緒に1つのFlagsTmp
インスタンスに結合できます。
template <typename E>
FlagsTmp<E> operator | (E e, E f) { return FlagsTmp<E>(e) | f; }
この演算子は、|
演算子をオーバーロードして、2つのenum
フラグまたは-dを一緒に。に変換しFlagsTmp
ます。
bitset
使用するソリューションを適応させたり、テスト方法や演算子を追加したりするなど、ニーズに合わせてこれを拡張する方法はいくつかあります。