为什么我可以使用卷曲括号来初始化一个来自另一个枚举类的值的枚举类?
我发现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%类型的安全。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是 cwg问题2374 。
在C ++ 17中,在解决此问题之前,指定具有单个表达式固定基础类型的枚举的直接列表限制,以始终等于功能性风格。然后,功能风格的铸件将等效于
static_cast
,并且实际上在不同的枚举类型之间允许(通过浏览促进的基础类型)。通过问题解决,只有当初始化器表达式将其隐式转换为枚举类型时,才能采用此路径,这不允许在不同的枚举类型之间转换。
这似乎是解决C ++ 17: CWG 2251
似乎Clang决定忠实地实施CWG 2251,并且仅解决CWG 2374后才恢复此特殊情况,而Clang 15将包含后者的修复
。在GCC 12之前似乎也适用。MSVC
似乎仅在符合模式下仅禁止转换(
/permissive -
或C ++ 20或更高版本),并且仅是因为V19.25。This is CWG issue 2374.
In C++17, before the resolution of this issue, direct-list-initialization of an enumeration with a fixed underlying type by a single expression was specified to always be equivalent to a functional style cast. A functional style cast then would be equivalent to a
static_cast
and that would actually be allowed between different enumeration types (by going through the promoted underlying type).With the issue resolution this path is taken only if the initializer expression is implicitly convertible to the enumeration type, which doesn't allow for conversion between different enumeration types.
That seems to have been an oversight in the resolution of a prior issue for C++17: CWG 2251
It seems that Clang decided to faithfully implement CWG 2251 and only revert this special case once CWG 2374 was resolved and the fix for the latter will be included with Clang 15.
For GCC the same seems to apply before GCC 12.
MSVC seems to forbid the conversion only in conformance mode (
/permissive-
or C++20 or later mode) and only since v19.25.这两者在C ++ 17和C ++ 20下的VS2022中为我产生了编译器错误。
Ubuntu上的GCC 9.3.0也会产生编译器错误。
也许这是一个特定的错误或扩展名? (也许Clang在使用括号初始化时尝试自动铸造?)
当使用clang “ noreferrer”>到版本14 。
clang(中继)的编译器错误:
Both of these produce compiler errors for me in VS2022 under C++17 and C++20.
GCC 9.3.0 on Ubuntu also produce compiler errors.
Perhaps this is a Clang-specific bug or extension? (Maybe Clang attempts to automatically cast when using bracket initialization?)
I was able to reproduce this behavior only when using Clang up to version 14.
Compiler error with Clang (trunk):