对于具有受限存储的枚举,类型转换在switch中失败

dyo*_*mas 5 c++ g++ switch-statement bit-fields enum-class

SSCCE:

enum class confirm {yes};

struct item
{
  confirm s:4; // (1) limiting storage size required
};

int main()
{
  item itm;

  itm.s = confirm::yes; // (2) OK

  switch (itm.s)
  {
    case confirm::yes: // (3) Failure, need static data cast here?
      break;
  }
}
Run Code Online (Sandbox Code Playgroud)

产生错误:

In function ‘int main()’:
error: could not convert ‘yes’ from ‘confirm’ to ‘int’
 case confirm::yes:
               ^
Run Code Online (Sandbox Code Playgroud)

g ++编译但用clang ++编译好.为什么分配标记为(2)可能但是由(3)标记的案例条款不是?

警告约too small storageofftopic

Sha*_*our 2

这看起来像是一个 gcc bug,我们可以看到它在最新的 gcc 版本中有效:

\n\n

来自 C++11 标准草案6.4.2 [stmt.switch]

\n\n
\n

该条件应为整型、枚举类型或存在到整型或枚举类型的单个非显式转换函数的类类型 (12.3)。[...] 执行积分促销。switch 语句中的任何语句都可以使用一个或多个 case 标签进行标记,如下所示:

\n\n
case constant-expression :\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中常量表达式应为switch 条件的提升类型的转换后的常量表达式 (5.19)。

\n
\n\n

转换后的常量表达式包含在5.19以下部分中:

\n\n
\n

[...]类型 T 的已转换常量表达式是隐式转换为 T 类型的文字常量表达式,\n 其中在文字常量表达式中允许隐式转换(如果有),并且隐式转换\n 序列仅包含用户定义的转换、左值到右值的转换 (4.1)、整数提升 (4.5)\n 以及除缩小转换 (8.5.4) 之外的整数转换 (4.7)。[ 注意:此类表达式可以用作 case 表达式 (6.4.2),如果基础类型是固定的,则可以用作枚举器初始值设定项 (7.2),也可以用作整型或枚举非类型模板参数 (14.3)。\xe2\x80\x94结束注] [...]

\n
\n\n

也许这与缺陷报告 1767: Scoped enumeration in a switch statements有关。因此,也许它强制升级为 int,然后本例中的比较就会失败。

\n