0

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')

エラーがここにあることを示す更新された例。

4

1 に答える 1