安全使用严格枚举 C++ 11
safe use strict enum c++ 11
如何在 c++ 11 中安全使用枚举?下面的代码,我正在尝试强制工作...
我需要安全的方法以适当的方式与严格枚举相互转换。
#include <iostream>
class test{
enum class fruits:int{
apple,
banana,
pear
}m_fruits{fruits::apple};
fruits operator=(int _i){
switch(_i){
case 0:
return fruits::apple;
case 1:
return fruits::banana;
case 2:
return fruits::pear;
default:
return fruits::apple;
}
}
int operator=(fruits _f){
return static_cast<int>(_f);
}
public:
void function_worked(){
fruits f = operator=(155);
std::cout << operator=(f);
}
void function_wanted(){
fruits f = 155;
std::cout << f;
}
};
unscoped enum
无作用域枚举的两个缺点是
它们污染了命名空间
{} 中的标识符泄漏到周围的范围内,这可能会让不知情的开发人员措手不及。更糟糕的是,开发人员的大脑倾向于为枚举器列表选择标识符,这些标识符在其他上下文中也可能有用。
enum Direction { x, y, z };
// ...
auto x = 42; // Error!
他们允许荒谬的语义悲剧
因为隐式转换为基础类型。
enum Direction { x, y, z };
Direction axis = x;
if (axis < 12.5)
std::cout sqrt(axis);
作用域枚举
解决了这两个问题,枚举器列表标识符不会泄漏到周围的范围内,并且没有隐式转换。
第一步,这是您决定使用作用域枚举时得到的。
宗教或工具
虽然一般来说,正确的设计应该顺利地与那些作用域枚举一起工作,但对老式语义悲剧的需求可能是错误设计决策的标志。我看不出有什么理由不利用作用域枚举的非作用域污染属性并故意放弃类型安全。
非类型安全+非范围污染仍优于非类型安全+范围污染
很难说为什么在问题的代码中需要
fruits f = 155;
什么时候你可以简单地写
fruits f = fruits::apple;
虽然两者都包含一定数量的魔法,但第一个要神秘得多,因为该枚举的明显逻辑并不表明 155 是一个苹果。
幸运的是,第一个表达式无法正常工作。
另一方面,如果它必须真的是一个 int 赋值,那么你只需要付出代价:
fruits f = static_cast<fruits>(155);
另一方面
std::cout << static_cast<int>(f);
对我来说似乎绝对没问题,例如用于调试或序列化或其他什么。
void function_wanted(){
fruits f = fruits::apple;
std::cout << static_cast<int>(f);
}
对我来说似乎是一个很好的解决方案。
备注
示例
fruits f = fruits::apple;
恕我直言,为什么枚举器名称在大多数情况下应该是单数的,尽管枚举定义包括大量标识符。
相关文章:
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 打印没有铸件的枚举可以在C++中吗?
- 枚举成员与静态 int 成员?
- C++:枚举:错误:应使用标识符而不是"}"
- 带有 c++ 的枚举(输入检查)
- 在 qml 中使用 Q_ENUM 和 Q_PROPERTY 作为枚举类
- 为什么 int 类型的枚举类值不能用作 int
- 在 C++ 中输出枚举类类型的向量元素