我还没有在C ++ 11标准中找到任何措辞,说明未编写的枚举被弃用,但从务实的角度来看,我不知道它们是否仍然有用。我的团队中有很多人养成了将未编写的enum转换为scoped enums的习惯,但它引起了一些麻烦:
class foo
{
public:
enum MyEnum { One, Two, Three };
};
他们将此转换为:
class foo
{
public:
enum class MyEnum { One, Two, Three };
};
这意味着当使用这些枚举数时,而不是foo::One
,它看起来像foo::MyEnum::One
。我一直在问以下最佳做法:
这两点之间的主要区别在于,对于#1,我们不会将它们放在类中,否则会增加一些冗长的间接性。
所有这些似乎都过于复杂化,并且似乎将枚举已经存在于类中作为未编译的枚举更简单。什么是决定两者之间的一般最佳实践方法?
答案 0 :(得分:5)
范围内的枚举数无法隐式转换为其基础类型。如果您需要枚举值隐式转换为其基础类型,则不能使用作用域枚举器。
这有用的一个示例是当您与控件中的API通信时,您的枚举值是位标志。需要uint32_t
或其他整数类型作为位标志的API(您无法控制)。
您可以覆盖operator|
等,以便将所有内容保存在“类型”中,或者让它们生成基础类型 - 但enum class
的单个元素无法隐式转换为uint32_t
}。
我觉得有用的无范围enum
的另一个用途是替换#define FOO 32
样式宏。我获得了一个具有相同含义的令牌,而不是文本替换,我不必重写代码库。如果存在一组紧密排列的此类值,我最终可以达到可以更改int
参数的点,这些参数期望这些#define
标记与enum
值一起传递,并且现在输入参数!
这允许逐步迁移到更好的代码库。
下一步可能是对这些值使用作用域枚举,但是必须立即执行所有操作的开销可能意味着可能不会采取第一步。完美是善的敌人。
另一方面,如果你的枚举实际上只是一组枚举值,并且它们在底层类型中的值是不重要的,那么范围内的枚举几乎总是比未经过编码的枚举更好。它们可以防止意外转换为基础类型:如果基础类型中的值仅仅是实现细节,则此类转换可能会导致错误。
这是我为enum
找到的最常见的用例 - 一组可分辨值,其基础类型和值仅仅是一个实现细节。