将枚举类的值用于位移移位运算符

时间:2019-01-28 08:09:49

标签: c++ visual-c++

以下代码段...

enum class A {
        X = 0, Y = 1, Z = 2,
    };

int s = (1 << A::X);

...产生以下编译错误:

error C2678: binary '<<': no operator found which takes a 
left-hand operand of type 'int' 
(or there is no acceptable conversion)

什么是使这种移位工作最好,最干净的方法?

3 个答案:

答案 0 :(得分:2)

小的实用程序功能可能有助于在确保正确性的同时澄清意图:

#include <type_traits>

template<class Enum>
auto to_bitmask(Enum e)
{
    using type = std::underlying_type_t<Enum>;
    return 1 << type(e);
};

https://godbolt.org/z/_pp7VW

对于更通用的版本,c ++ 17可以轻松处理任何枚举或整数类型:

template<class Enum>
constexpr auto to_bitmask(Enum e)
{
    static_assert(std::is_integral<Enum>() || std::is_enum<Enum>());

    if constexpr (std::is_enum<Enum>())
    {
        using type = std::underlying_type_t<Enum>;
        return 1 << type(e);
    }
    else 
    {
        return 1 << e;
    }
}

答案 1 :(得分:1)

作用域枚举是强类型的。您需要明确定义要支持的运算符,因为没有隐式转换为整数,可以使内置运算符可行。

如果要启用隐式转换为int的功能,而又不放弃标识符范围,则可以使用“旧样式”范围内的枚举。即,将其包装为类类型:

struct A {
   enum Type {
        X = 0, Y = 1, Z = 2,
   };
};

由于无作用域的枚举器也是封闭范围的成员,因此您可以仍然写1 << A::X,它将产生所需的效果。当然,代价是现在枚举名称更加冗长A::Type

答案 2 :(得分:0)

以下方式起作用。 Cmd:g ++ test.cc

#include <iostream>
int main(){
    enum A {
        X = 0, Y , Z
    };

    int s = (1 << Y);
    std::cout <<"s = "<< s << std::endl;
}