![](/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.