如何将bitmask_operators.hpp与命名空间和类一起使用

时间:2017-02-27 08:41:46

标签: c++11 templates bit-fields bitmask enum-class

我想使用C ++ 11 enum class作为位域并找到一个很好的方法here

但我坚持,如果我的枚举类声明不在全局命名空间中,而是在自定义命名空间中或在类内部。 E.g:

#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相同的命名空间(本例中为全局命名空间)。

但我想让我的专业化接近我的枚举类声明。

在上面提到的article中,Jay Miller也评论了这个问题,似乎他提供了一个解决方案。但我没有按照他的提示在bitmask_operators.hpp中解决这个问题。

示例代码here

编辑/部分解决:与此同时,我得到了它的工作(只是一个转储副本和粘贴问题以及神秘的错误消息;-)。我通过应用Jay Millers constexpr功能解决方案更新了我的example code

但是在类中声明枚举类时仍然存在问题。当我向班级添加一个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')

更新示例,显示错误位于here

1 个答案:

答案 0 :(得分:1)

示例代码,基于Anthony Williams&#39; bitmask_operators.hpp并且还应用Jay Millers建议(constexpr函数而不是模板&lt;&gt; struct)来修复命名空间问题位于here

请注意,在类中声明枚举类时,constexpr函数需要以friend关键字开头(如下面的注释中建议的dyp)。例如:

class Myclass {
public:
    enum class E {
        None = 0x00,
        Bit0 = 0x01,
        Bit1 = 0x02,
        Bit2 = 0x04,
        Bit3 = 0x08,
    };
    friend ENABLE_BIT_OPERATORS(E)
};