"enum class" 的增量和减量

30

众所周知,C++03中的enum不支持增减操作,因为C++03中的enum可能是非连续的。但是C++11标准引入了新的enum class构造,据维基百科称它更加类型安全,因为它不是建立在任何简单可数类型之上的。因此,现在如果我们有一个有限的枚举值列表,我们能否编写类似以下的代码:

enum class Colors { Black, Blue, White };
// ...
Colors color = Colors::White;
color++;

并且它能够正确地工作吗(例如,对White进行递增将返回Black,对Black进行递减将返回White)?

如果我们无法编写这样的代码,您是否知道任何类似于行为的类,可以从boostQt中提供此功能(在递增和递减时是正确的)?


1
没有什么可以说明类枚举的值是连续的。在这方面,它们与C++03枚举相同。 - juanchopanza
可能是在循环中使用枚举和值一致性的重复问题。 - Bo Persson
2
@juanchopanza:C++03枚举类型继承了C语言的行为,即按顺序分配值。每个没有初始化器的枚举项都是前一个枚举项+1。如果第一个枚举项没有初始化器,则其值为零。这完全是有保障和标准化的,自从有了标准以来就一直如此。请参见第7.2p2节。 - Ben Voigt
3
谁告诉你enum class不是建立在基本整型上的?唯一的区别是现在你可以选择基础类型,而不是由编译器以实现依赖的方式自动选择。 - Ben Voigt
1
枚举类型可表示的值范围始终是连续的。该范围内赋予哪些值以显式名称,哪些不赋予,完全无关紧要。不能使用上述运算符与枚举对象无关其连续性的事实。 - AnT stands with Russia
显示剩余4条评论
1个回答

37

它能正常工作吗?

不行。enum默认情况下没有设计成以你描述的方式“循环”。

C++11的enum class也不保证连续的值,与你描述C++03的enum的情况相同。

但是,你可以为特定的枚举类型定义这种包装行为。 这个解决方案假设数值是连续的,就像你所描述的那样。

enum class Colors { Black, Blue, White, END_OF_LIST };

// Special behavior for ++Colors
Colors& operator++( Colors &c ) {
  using IntType = typename std::underlying_type<Colors>::type
  c = static_cast<Colors>( static_cast<IntType>(c) + 1 );
  if ( c == Colors::END_OF_LIST )
    c = static_cast<Colors>(0);
  return c;
}

// Special behavior for Colors++
Colors operator++( Colors &c, int ) {
  Colors result = c;
  ++c;
  return result;
}

5
有没有一种方法可以在不使用强制类型转换的情况下实现 ++ 运算符?我想不到任何方法,但这个实现方式让我感到不舒服。强制类型转换通常意味着存在问题,必须有非常充分的理由才能使用它们。我希望编程语言能够允许实现 ++ 运算符而无需强制指定类型。 - SomeWittyUsername
1
非连续的enum class怎么办?迭代允许值的范围是一种非常自然的操作,即使使用强制转换也无法实现。 - SomeWittyUsername
3
这是因为实际上不存在这种情况。因此,在大多数情况下,“枚举”并不是特别有用的构造。 - Cubic
如果你需要一个状态机,那就直接使用一个状态机;试图使用枚举来做一些它不适合的事情只会适得其反。 - ildjarn
是否可能将此模板化以适用于 任何 枚举类,而不仅仅是一个特定的 enum class?如果我有10个不同的枚举类,我会认为维护所有这些用于递增每种类型的 enum classoperator++() 过载是过于复杂的。注意:我并不太关心环绕功能,只关心基本的递增功能。我想让我的递增更加简洁 在我的答案中 - Gabriel Staples
显示剩余8条评论

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