#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;
对于本地枚举类,这似乎是不可能的,但也许你可以用类来模拟枚举类:
在这种情况下,
enum class b
{
B1,
B2
};
相当于:
class b {
private:
int underlying;
public:
static constexpr int B1 = 0;
static constexpr int B2 = 1;
b(int v) : underlying(v) {}
operator int() {
return underlying;
}
};
这在很大程度上相当于最初的enum类。你可以在返回类型为b的函数中直接返回b::B1 for。你可以用它来切换大小写,等等。
根据本例的精神,您可以使用模板(可能与其他东西一起使用)泛化和模拟枚举类语法定义的任何可能的对象。