为什么不是这个有效的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
,或某个结构,或者什么不是,我会收到此错误。但在语义,类型安全等方面,这对我来说似乎是完全合法的。我缺少什么?
答案 0 :(得分:8)
C ++ 11 [dcl.enum] / 2:
enum-base 的 type-specifier-seq 应命名为整数类型;任何cv资格都会被忽略。
枚举本身不是整数类型 - [basic.fundamental] / 7:
类型
public List<Category> GetCategoryByID(int menuID) { return db.Table<Category>().Where(x => x.menu_ID == menuID).ToList(); }
,bool
,char
,char16_t
,char32_t
以及有符号和无符号整数类型统称为 integral 类型。
这附有一个非规范的脚注:
因此,枚举不是不可或缺的;但是,枚举可以提升为[conv.prom]中指定的整数类型。
为了达到我认为你正在寻找的效果,但仍然很简单:
wchar_t
答案 1 :(得分:4)
当您向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
应该表达的内容提出建议并说服委员会足够多之前,不太可能允许这样做。当存在多种不同的合理含义时,这使得任何一种意义的选择变得更加困难。人们需要一个强有力的用例,为什么一个特定的意义是最好的,为什么值得努力将其纳入标准。
答案 2 :(得分:3)
嗯,不完全一样,但我认为你可以使用std::underlying_type
:
enum foo : unsigned { first_foo, second_foo };
enum bar : std::underlying_type_t<foo> { best_foo = first_foo };
答案 3 :(得分:3)
对我而言,说枚举可以基于另一个枚举是一个逻辑错误。如果您认为base是存储在枚举中定义的值的存储类型,那么我无法将其作为逻辑表达式来表示存储类型是枚举。因为枚举不仅是存储类型,还包含一组有效值。
如果我们能写出类似的东西:
enum A: int { ONE, TWO };
应该是什么意思:
enum B: A{};
因为A不仅定义了底层类型(我称之为存储类型)而且定义了一组有效值,B应该只是枚举A的一个子集,这意味着您只能定义已经在A中定义的值吗? / p>
现在说我们是否已经在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 };
也有效吗?我不相信! ;)
从逻辑点(我的观点)来看,枚举的底层类型是它的存储类型。将枚举作为另一个枚举的底层存储类型毫无意义。