【问题标题】:safe use strict enum c++ 11安全使用严格枚举 C++ 11
【发布时间】:2017-08-25 11:26:01
【问题描述】:

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

   };

【问题讨论】:

  • 你能具体说明什么不起作用吗?
  • 您确定要将枚举转换为整数,反之亦然吗?这里的目标是什么?
  • function_wanted() 中的构造不可编译,但我想使用它。 function_worked() 是可行的,但这看起来像......
  • enum class 的目的是禁止您尝试执行的操作。如果您要颠覆这些功能,您应该使用普通的enum
  • 是的,我真的很想要这个。例如设置文件中的值保存为数字,但我想解释为枚举

标签: c++ enums type-conversion


【解决方案1】:

无范围枚举

无范围枚举的两个缺点是

它们污染了命名空间

{} 中的标识符泄漏到周围的范围内,这可能会让不知情的开发人员措手不及。更糟糕的是,开发人员的大脑倾向于为枚举器列表选择在其他情况下也可能有用的标识符。

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;

说明了为什么枚举器名称在大多数情况下应该是单数的,尽管枚举定义包含多种标识符。

【讨论】:

  • 好的。感谢您的回答。 fruits f = 155 构造必须是无错误的,即值 155 不在枚举中,枚举 f 必须仍然正确。
  • 你真的应该花更多的时间准确地陈述你的问题!
  • 我没有任何问题。我唯一真正想要的就是写代码,它不能以不必要的方式运行,而且仍然优雅而简单;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多