![](/img/trans.png)
[英]Why do I have to explicitly cast an enum that I have specified the underlying type for?
[英]Why can't I have an enum as the underlying type of another enum?
为什么这个有效的C ++不是?:
enum foo : unsigned { first_foo, second_foo };
enum bar : foo { best_foo = first_foo };
GCC 5.4.0说:
/tmp/a.cpp:3:16: error: underlying type ‘foo’ of ‘bar’ must be an integral type
enum bar : foo { best_foo = first_foo };
我可以理解为什么如果foo
是一个float
,或者某个结构,或者什么不是,我会得到这个错误。 但就语义,类型安全等而言,这似乎是完全合法的。我缺少什么?
C ++ 11 [dcl.enum] / 2:
枚举的类型说明符-seq应命名为整数类型; 任何cv资格都被忽略了。
枚举本身不是整数类型 - [basic.fundamental] / 7:
类型
bool
,char
,char16_t
,char32_t
,wchar_t
以及有符号和无符号整数类型统称为整数类型。
这附有一个非规范性的脚注:
因此,枚举不是不可或缺的; 但是,枚举可以提升为[conv.prom]中指定的整数类型。
为了达到我认为你正在寻找的效果,仍然很简单:
enum bar : std::underlying_type<foo>::type { best_foo = first_foo };
当您向C ++添加内容时,您倾向于添加解决问题的最小量。
enum A:int
语法允许您准确指定enum A
如何存储为整数。 这就是它所做的一切,它解决了这个问题。
enum A:B
其中B
是枚举可能有很多含义。 A
可以扩展B
,或者A
可以是具有不同名称的B
基础类型的子集,或者A
可以是严格限制为具有可以存储在B
内的值的子集的枚举,或者A
可以是其值的枚举仅限于B
值的“船体”。
其中,“相同的底层类型”解决方案(使用:int
语法)与enum A:std::underlying_type_t<B>
。 所以已经有办法做到这一点,并不是特别繁琐。
直到有人对enum A:B
应该意味着什么并且说服委员会足够多的人提出建议,这是不可能被允许的。 当存在多种不同的合理含义时,这使得任何一种意义的选择变得更加困难。 人们需要一个强有力的用例,为什么一个特定的意义是最好的,为什么值得努力将其纳入标准。
好吧,不完全相同,但我认为你可以使用std::underlying_type
:
enum foo : unsigned { first_foo, second_foo };
enum bar : std::underlying_type_t<foo> { best_foo = first_foo };
对我来说,说枚举可以基于另一个枚举是一个逻辑错误。 如果您认为base是存储在枚举中定义的值的存储类型,那么我无法将其作为逻辑表达式来表示存储类型是枚举。 因为枚举不仅是存储类型,还包含一组有效值。
如果我们可以这样写:
enum A: int { ONE, TWO };
应该是什么意思:
enum B: A{};
因为A不仅定义了底层类型(我称之为存储类型)而且还定义了一组有效值,B应该只是枚举A的一个子集,这意味着您只能定义已在A中定义的值?
现在说我们是否已经在B中定义了两个值? 现在可以添加更多值,例如:
enum B: A{THREE};
所有有效值现在是一,二,三?
或者是我们只得到子集的意思:
enum B: A{ONE};
这意味着B只能使用已在A中定义的值。简单地说,这使得我很难将枚举作为另一个枚举的基础。
如果你打开那扇门,你也可以想到你想要使用其他类型的底层存储类型,比如位域。
struct A { unsigned int a : 3; unsigned int B: 2; };
应该
enum B: A { ONE, TWO };
也有效吗? 我不相信! ;)
从逻辑点(我的观点)来看,枚举的底层类型是它的存储类型。 将枚举作为另一个枚举的底层存储类型毫无意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.