当前位置: 首页 > 知识库问答 >
问题:

为什么我可以使用花括号用另一个枚举类的值初始化一个枚举类?

赵智
2023-03-14

我发现了Clang-12、Clang-13和Clang-14在c 17标准中的以下行为:

enum class FOO {
  VALUE
};

enum class BAR {
  VALUE
};

FOO value1{BAR::VALUE}; // OK
FOO value2 = BAR::VALUE; // Error

为什么有区别?我希望枚举类是100%类型安全的。

编译器资源管理器


共有2个答案

郎建章
2023-03-14

这两种方法都会在VS2022的C 17和C 20下为我产生编译器错误。

Ubuntu上的GCC 9.3.0也会产生编译器错误。

也许这是一个特定于叮当声的bug或扩展?(可能是Clang在使用括号初始化时尝试自动强制转换?)

只有在使用版本14之前的叮当声时,我才能复制这种行为。

编译器Clang错误(主干):

error: cannot initialize a variable of type 'FOO' with an rvalue of type 'BAR'
FOO value{BAR::VALUE};
          ^~~~~~~~~~
张德佑
2023-03-14

这是CWG第2374期。

在C17中,在解决这个问题之前,通过单个表达式对具有固定基础类型的枚举进行直接列表初始化被指定为始终等效于函数样式强制转换。函数样式强制转换将等效于static_cast,并且在不同的枚举类型之间实际上是允许的(通过提升的基础类型)。

对于问题解决方案,只有当初始值设定项表达式隐式转换为枚举类型时,才采用此路径,这不允许在不同枚举类型之间进行转换。

这似乎是在解决C 17之前的一个问题时的疏忽:CWG 2251

看来,Clang决定忠实地实施CWG 2251,只有在解决CWG 2374后才恢复此特殊情况,后者的修复将包含在Clang 15中。

对于海湾合作委员会来说,这似乎也适用于海湾合作委员会第12届会议之前。

MSVC似乎只在一致性模式(/permissive-或C 20或更高版本模式)下禁止转换,并且仅从v19.25开始。

 类似资料:
  • 问题内容: 我想分享一些枚举属性。就像是: 我知道了为什么不能继承(因为状态在中没有表示形式),但是我仍然想说“ ActionState就像具有更多选项的State,并且ActionState可以获取类型为State的输入,因为它们也属于输入ActionState” 我知道如何获得上述逻辑来复制案例并在函数中进行切换。但我正在寻找更好的方法。 我知道枚举不能在Swift中继承,并且我已经阅读了sw

  • 所以我有一个Scala枚举对象: 我想初始化一个新的ValueSet实例,仅存在一个值。用最短的速记: 很有魅力。然而,要从一个值创建一个值集,我必须更加明确:(尤其是在枚举对象类上有多个) 从一个值创建枚举会产生一个值(如预期的那样),但不是我想要的(一个值集): 常规方法是: 不雅观的方式: 冗长的方法——工作正常,但我追求简洁 我还能用其他速记法吗?i、 e val eKnot=塞子/一些简

  • 我听到一些人建议在C++中使用枚举类,因为它们的类型安全。 但这到底意味着什么呢?

  • 问题内容: 以下是有效的枚举声明。 但是我可以用枚举类型覆盖抽象类吗? SomeEnumClass.java OverrideingEnumClass.java 如果没有,为什么不呢?有什么好的选择? 问题答案: 不,你不能;枚举类型全部扩展,并且是隐式的。枚举可以实现接口,也可以直接在有关的枚举类上声明相关方法。 (我确实看到了您想要的基本概念,它是一个mixin;也许Java 8接口在这方面会

  • 问题内容: 我有几个需要国际化的枚举(我需要将枚举值转换为某些语言才能在jsf页面中显示)。考试列举: 翻译将是例如/ 转换应存储在MessageBundle(属性文件)中。我正在寻找一个简单,通用的解决方案(最好是无需在所有枚举中编写额外的代码),而该解决方案在jsf方面并不需要太多。仅提及它,当然,两个不同的枚举可能具有相同的枚举值(例如,类似的值在不同的枚举中具有不同的含义)。 我想出的解决

  • 当我们需要定义常量时,一个办法是用大写变量通过整数来定义,例如月份: JAN = 1 FEB = 2 MAR = 3 ... NOV = 11 DEC = 12 好处是简单,缺点是类型是int,并且仍然是变量。 更好的方法是为这样的枚举类型定义一个class类型,然后,每个常量都是class的一个唯一实例。Python提供了Enum类来实现这个功能: from enum import Enum