安全使用严格的枚举c ++ 11

时间:2017-08-25 11:26:01

标签: c++ enums type-conversion

如何在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;
     }

   };

1 个答案:

答案 0 :(得分:0)

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);

scoped enum

解决了这两个问题,枚举器列表标识符不会泄漏到周围的范围内,也没有隐式转换。

第一步是您决定使用作用域枚举时获得的结果。

宗教或工具

虽然一般来说,一个正确的设计应该顺利地与那些范围内的词汇一起使用,并且对旧学校语义悲剧的需求可能是一个糟糕的设计决策的标志。我没有看到任何理由不利用scoped枚举的非范围污染属性并故意放弃类型安全。

非类型安全+非范围污染仍然优于非类型安全+范围污染

很难说为什么在问题的代码中应该有任何需要

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;

显示imho为什么枚举器名称在大多数情况下应该是单数的,尽管枚举定义包含多个标识符。