标准在7.2/5 [dcl.enum]
:
如果基础类型未修复,则每个枚举器的类型先于 结束括号的确定如下:
(5.1) - 如果为枚举器指定了初始值设定项,则为 constant-expression应该是一个整数常量表达式(5.20)。 如果表达式具有unscoped枚举类型,则枚举器具有 枚举类型的基础类型,否则它具有 与表达式相同的类型。
(5.2) - 如果没有为第一个枚举器指定初始值设定项,则为 type是未指定的有符号整数类型。
(5.3) - 否则枚举器的类型与。的类型相同 前面的枚举器,除非递增的值不是 在该类型中可表示,在这种情况下,类型是未指定的 积分类型足以包含递增的值。如果没有这样的话 类型存在,程序格式不正确。
因此,5.1
和5.2
涵盖了以下所有情况:
我。 enum A { x = 4 }; //case 1, initializer was specified
II。 enum B { x, y }; //case 2, initializer was not specified.
III。
enum C { x = 5 };
enum D { y = x }; // case 1, y had unscoped enumeration type.
IV
enum struct C { x = 5 };
enum D { y = 0, x = C::x }; // even integral constant expression must have integral
// or unscoped enumeration type, not 'C
我想看一下5.3
案例。为什么IV
无法编译?
答案 0 :(得分:1)
将范围枚举引入语言的重点是防止隐式转换为基础类型。所以在你失败的例子中,没有办法隐式地从C::x
转换为D
的基础类型的整数类型。
添加适当的强制转换,并编译代码。
#include <type_traits>
enum struct C { x = 5 };
enum D
{
y = 0,
x = static_cast<std::underlying_type<C>::type>(C::x)
};
答案 1 :(得分:0)
7.2 / 5 在enum-specifier的右括号之后,每个枚举器都有其枚举类型。
因此,在D
的定义中,C::x
的类型为C
。
5.19 / 3 整数常量表达式是整数或无范围枚举类型的表达式...
强调我的。所以C::x
不是一个整数常量表达式,不能作为枚举器的初始化器。