C++11 をビットフィールドとして使用し、ここでenum class
適切なアプローチを見つけたいと考えています。
しかし、列挙型クラス宣言がグローバル名前空間ではなく、カスタム名前空間またはクラス内にある場合、私は立ち往生しました。例えば:
#define ENABLE_BIT_OPERATORS(E) template<> struct enable_bitmask_operators<E> { static constexpr bool enable=true; };
// anonymous namespace
namespace {
enum class Ean {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
ENABLE_BIT_OPERATORS(Ean)
} // anonymous namespace
// custom namespace
namespace Custom {
enum class Ecn {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
ENABLE_BIT_OPERATORS(Ecn)
} // custom namespace
// inside class in global namespace
class MyclassGN {
public:
enum class Ecgn {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
ENABLE_BIT_OPERATORS(Ecgn)
};
// inside class in anonymous namespace
namespace {
class MyclassAN {
public:
enum class Ecan {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
ENABLE_BIT_OPERATORS(Ecan)
};
} // anonymous namespace
// inside class in custom namespace
namespace Custom {
class MyclassGN {
public:
enum class Ecgn {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
ENABLE_BIT_OPERATORS(Ecgn)
};
} // custom namespace
これは常に私にエラーを与えます:
error: specialization of 'template<class E> struct enable_bitmask_operators' in different namespace
テンプレートの特殊化を、テンプレートが配置されているのと同じ名前空間enable_bitmask_operators
(bitmask_operators.hpp
この場合はグローバル名前空間) に配置するまで。
しかし、特殊化を enum クラス宣言の近くに置きたいと思っています。
言及された記事では、この問題は Jay Miller によってもコメントされており、彼は解決策を提供しているようです。しかし、私は でこれを解決するための彼のヒントに従わなかったbitmask_operators.hpp
.
サンプルコードはこちら。
編集/部分的に解決しました:その間、私はそれを機能させました(ダンプのコピーと貼り付けの問題と不可解なエラーメッセージだけです;-)。Jay Millers の constexpr 関数ソリューションを適用して、サンプル コードを更新しました。
ただし、クラス内で列挙型クラスを宣言する場合は、まだ問題があります。クラスに ctor を追加すると、次のように問題が発生します。
class MyclassGN {
public:
enum class Ecgn {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
ENABLE_BIT_OPERATORS(Ecgn)
explicit MyclassGN(Ecgn e_) {}
};
次に、エラーが発生しました:
enclosing class of constexpr non-static member function 'bool MyclassGN::enable_bitmask_operators(MyclassGN::Ecgn)' is not a literal type
さて、static
キーワードを追加してこれを修正しました:
class MyclassGN {
public:
enum class Ecgn {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
static ENABLE_BIT_OPERATORS(Ecgn)
explicit MyclassGN(Ecgn e_) {}
};
しかし、ビットマスク演算子を使用しようとすると、次の問題が発生します。
class MyclassGN {
public:
enum class Ecgn {
None = 0x00,
Bit0 = 0x01,
Bit1 = 0x02,
Bit2 = 0x04,
Bit3 = 0x08,
};
static ENABLE_BIT_OPERATORS(Ecgn)
explicit MyclassGN(Ecgn e_): e(e_) {
e |= Ecgn::Bit3;
}
private:
Ecgn e;
};
エラーが発生しました:
no match for 'operator|=' (operand types are 'MyclassGN::Ecgn' and 'MyclassGN::Ecgn')
エラーがここにあることを示す更新された例。