用于强类型枚举的模板运算符

时间:2019-01-11 11:04:05

标签: c++ enums operator-overloading

我有两个基础类型为uint32_t的枚举。并且我需要constexpr OR运算符,因为某些成员应该与其他成员的OR结果组成。我想避免两次或多次实施该运算符。

因此,我尝试使用模板来实现它。

    template <enum class E>
    constexpr uint32_t operator|(const E&   left, const E& right)
    {
        return (uint32_t)left | (uint32_t)right;
    }

    template <enum class E>
    constexpr uint32_t operator|(const uint32_t& left, const E& right)
    {
        return left | (uint32_t)right;
    }

    enum class U32Enum1 : uint32_t { 
        OtherMember1 = 0x01L,
        OtherMember2 = 0x02L,
        SomeOfMember = OtherMember1 | OtherMember2 // Not work
    }

    enum class U32Enum2 : uint32_t {
        OtherMember1 = 0x01L,
        OtherMember2 = 0x02L,
        SomeOfMember = OtherMember1 | OtherMember2 // Not work    
    }

但是,它不起作用,编译器给我一条消息,表示运算符|没有匹配的操作数。我该怎么做?

1 个答案:

答案 0 :(得分:3)

template <enum class E>不是很好的语法,您可以这样做:

template <class E, std::enable_if_t<std::is_enum<E>::value, int> = 0>
constexpr E operator|(const E&   left, const E& right)
{
    return static_cast<E>((uint32_t)left | (uint32_t)right);
}

使用基础类型甚至更好:

template <class E, std::enable_if_t<std::is_enum<E>::value, int> = 0>
constexpr E operator|(const E&   left, const E& right)
{
    using T = typename std::underlying_type<E>::type;
    return static_cast<E>(static_cast<T>(left) | static_cast<T>(right));
}