【问题标题】:Type cast failed in switch for enum with restricted storage类型转换在具有受限存储的枚举的开关中失败
【发布时间】:2015-08-27 15:07:08
【问题描述】:

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 的警告是offtopic

【问题讨论】:

  • “这是一个 gcc 错误”会是一个足够的答案吗? (自然有证据表明它应该被允许)
  • @Yakk:有疑问
  • @dyp:感谢您的标记,但有一个问题是针对 enum class 的——仅限 C++11;以前的标准没有这样的问题
  • 我必须在 C++11 标签和其他一些标签之间进行选择(最多 5 个标签);我的理由是:[enum-class] 暗示 C++11,因此从标签中可以清楚地看出这是 >= C++11。三个 [switch-statement]、[bit-fields] 和 [enum-class] 描述了 [g++] 中的问题。我猜 [c++11] 标记无论如何都会在一段时间内变得多余,我看到各种问题已经接受了没有 [c++11] 标记的 C++11 答案。

标签: c++ g++ switch-statement bit-fields enum-class


【解决方案1】:

这看起来像一个 gcc 错误,我们可以看到这是有效的 in the latest gcc version:

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

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

case constant-expression :

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

5.19 部分介绍了转换后的常量表达式:

[...]T 类型的转换常量表达式是一个字面常量表达式,隐式转换为 T 类型, 在文字常量表达式中允许隐式转换(如果有)和隐式转换 序列仅包含用户定义的转换、左值到右值的转换 (4.1)、积分提升 (4.5)、 和积分转换 (4.7),而不是窄化转换 (8.5.4)。 [注:可以使用这样的表达方式 作为 case 表达式 (6.4.2),如果基础类型是固定的 (7.2),则作为枚举器初始化器,以及作为整数或 枚举非类型模板参数 (14.3)。 ——尾注] [...]

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2012-03-26
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    相关资源
    最近更新 更多