5

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

产生错误:

In function ‘int main()’:
error: could not convert ‘yes’ from ‘confirm’ to ‘int’
 case confirm::yes:
               ^

虽然用g++编译,但用clang++编译得很好。为什么用 (2) 标记的赋值可能但用 (3) 标记的case子句不行?

too small storage关于离题的警告

4

1 回答 1

2

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

从草案 C++11 标准部分6.4.2 [stmt.switch]

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

case constant-expression :

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

转换后的常量表达式在一节5.19中介绍:

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

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

于 2015-09-18T20:07:34.073 回答