C++11与C++之间枚举的区别

3
//c++03
enum Something
{
    S1 = 0,
    S2,
    SCOUNT
};
int arr[SCOUNT];

//c++11
enum class Something
{
    S1 = 0,
    S2,
    SCOUNT
};
int arr[(int) Something::SCOUNT];

在不将枚举计数转换为整数的情况下,我该如何在这种情况下使用枚举?


1
第一个版本仍然可以在C++11中工作,但我想你想要利用实际枚举成员的好处,并且只想获得枚举成员的数量? - user395760
“enum class”的好处不就是你不能混合使用不同枚举类型的值吗? - Appleshell
2个回答

10
在这种情况下,如何在不将枚举计数转换为整数的情况下使用枚举?你不能...但是你可以删除enum class中的class关键字。class关键字意味着你无法隐式地在枚举和整数之间进行转换。删除class关键字意味着你的枚举将以与C++早期版本相同的方式工作。你不需要进行转换,但是通过允许隐式地将枚举类型强制转换为整型值,你会失去strongly typed enums的安全性。
//C++11
enum class Something
{
    S1 = 0,
    S2,
    SCOUNT
};
int arr[SCOUNT]; // ERRROR

//C++11
enum Something
{
    S1 = 0,
    S2,
    SCOUNT
};
int arr[SCOUNT]; // OK

您可以在这里了解有关强类型枚举的更多信息。


另一个选项是像您所做的那样进行转换。但是,您应该避免使用旧的C风格强制转换,而应改用static_cast<>,因为它具有更好的类型安全性并更明确。

//C++11
enum class Something
{
    S1 = 0,
    S2,
    SCOUNT
};
int arr[static_cast< size_t > ( SCOUNT ) ]; // OK

5

实际上,在第二种情况下,您不能不进行强制转换就写出那样的代码。

既然您必须使用强制转换,现在可以使用更好的强制转换方式而不是 C 风格的强制转换:

int arr[to_integral(Something::SCOUNT)];

to_integral 的定义如下:

#include <type_traits> //it is where std::underlying_type is defined

template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type 
{
   return static_cast<typename std::underlying_type<E>::type>(e);
}

现在这个函数模板是可重用的。您可以将其用于任何符合C ++11样式的枚举类型。它还推断出底层类型,因此您不必再在代码中提及它。有关详细解释,请参见此答案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接