#include <iostream>
struct a {
enum LOCAL_A { A1, A2 };
};
enum class b { B1, B2 };
int foo(int input) { return input; }
int main(void) {
std::cout << foo(a::A1) << std::endl;
std::cout << foo(static_cast<int>(b::B2)) << std::endl;
}
a::LOCAL_A是强类型enum试图实现的目标,但有一个小小的区别:普通enum可以转换为整数类型,而强类型enum如果没有强制转换就不能做到这一点。
那么,有没有一种方法可以将强类型枚举值转换为整数类型而不进行强制转换呢?如果是,怎么做?
由R. Martinho Fernandes提供的答案的c++ 14版本将是:
#include <type_traits>
template <typename E>
constexpr auto to_underlying(E e) noexcept
{
return static_cast<std::underlying_type_t<E>>(e);
}
与前面的答案一样,这将适用于任何类型的枚举和底层类型。我添加了noexcept关键字,因为它永远不会抛出异常。
更新
这也出现在Scott Meyers的《Effective Modern c++》中。见第10项(在我这本书的最后几页有详细说明)。
c++ 23版本将使用std:: to_底层函数:
#include <utility>
std::cout << std::to_underlying(b::B2) << std::endl;
...或者如果底层类型可以是1字节类型:
std::cout << +(std::to_underlying(b::B2)) << std::endl;
c++委员会向前迈出了一步(将枚举范围从全局命名空间中排除),又后退了五十步(没有枚举类型衰减为整数)。遗憾的是,如果您需要以任何非符号的方式获取枚举的值,枚举类是不可用的。
最好的解决方案是根本不使用它,而是自己使用名称空间或结构来确定枚举的范围。出于这个目的,它们是可以互换的。当引用枚举类型本身时,您将需要输入一些额外的内容,但这种情况可能不会经常发生。
struct TextureUploadFormat {
enum Type : uint32 {
r,
rg,
rgb,
rgba,
__count
};
};
// must use ::Type, which is the extra typing with this method; beats all the static_cast<>()
uint32 getFormatStride(TextureUploadFormat::Type format){
const uint32 formatStride[TextureUploadFormat::__count] = {
1,
2,
3,
4
};
return formatStride[format]; // decays without complaint
}