首页 > 解决方案 > Scoped Enums(枚举类)关系运算符

问题描述

我到处看了看,我不敢相信这个问题以前没有被问过。

范围枚举器的顺序是否由标准定义?说如果我有以下

#include <iostream>

enum class Fruits {Apple, Orange, Tomato};

int main(){

   std::cout << (Fruits::Apple < Fruits::Orange);
   std::cout << (Fruits::Orange > Fruits::Tomato);
   return 0;
}


// output:
// 1 0

这在 g++ 中输出 1 0。但是这个标准或编译器是特定的吗?

标签: c++c++11enum-classrelational-operators

解决方案


要完成图片并确认是,定义了排序。我们从为什么可以将两个枚举数放在一个关系表达式中开始......

[expr.rel]

2通常的算术转换是在算术或枚举类型的操作数上执行的......

5如果两个操作数(转换后)都是算术或枚举类型,则如果指定的关系为真,则每个运算符都应返回真,如果为假,则返回假。

...其中范围枚举的通常算术转换是无操作的...

[表达式]

9许多期望算术或枚举类型的操作数的二元运算符会导致转换并以类似的方式产生结果类型。目的是产生一个通用类型,这也是结果的类型。这种模式称为通常的算术转换,其定义如下:

  • 如果任一操作数属于范围枚举类型 ([dcl.enum]),则不执行任何转换;如果另一个操作数的类型不同,则表达式格式错误。

所以它们不会转换,只能与相同类型的对象进行比较。给枚举器的值(由另一个答案指定)决定了“如果指定的关系为真,则每个运算符都应产生真,如果为假,则应产生假”。这样比较就完成了。

还值得注意的是,枚举类型变量可以采用未枚举的值!那么例如...

enum class foo {
  min, max = 10
};

foo mid = static_cast<foo>(5);

... 是有效的,并且比较mid > foo::min将保持不变,因为前面的段落被概括为不仅仅包括命名值。


推荐阅读