【问题标题】:templated operator for strongly typed enumerations用于强类型枚举的模板化运算符
【发布时间】:2019-01-11 11:04:05
【问题描述】:

我有两个基础类型为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    
    }

但是,它不起作用,编译器给了我一条消息,指出运算符 | 没有匹配的操作数。我怎样才能做到这一点?

【问题讨论】:

  • 请提供minimal reproducible example和错误信息
  • 不能转换为基础类型,然后简单地将现有的operator| 用于uint32_t 吗?
  • @user463035818 示例中仅描述了两个成员,但此情况涉及更多成员。我可以将它们中的每一个都转换为底层类型,但是它会弄乱代码。

标签: c++ enums operator-overloading


【解决方案1】:

template &lt;enum class E&gt; 不是很好的语法,你可以这样做:

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));
}

【讨论】:

  • template &lt;enum class E&gt; 需要 E 类型的枚举值,而不是类型?我对这种语法有点困惑
  • @user463035818: 我收到了template &lt;enum class E&gt; 的警告(“作用域枚举的详细类型说明符不能使用'class'关键字”),所以事实上template &lt;enum class E&gt;template &lt;enum E /*e*/&gt; 甚至是 template &lt;E /*e*/&gt;
  • 我尝试了您的解决方案,但仍然显示相同的错误消息,E3049,no operator "|" matches these operands
  • 哦,我打错字了。当我修改它时,问题就消失了!感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多