是否有可能確定一個C enum class
的++基數:是否可以確定一個C++枚舉類的元素的數量?
enum class Example { A, B, C, D, E };
我試圖使用sizeof
,但是,它返回一個枚舉元素的大小。
sizeof(Example); // Returns 4 (on my architecture)
是否有一個標準的方法來獲得基數(在我的例子中是5)?
是否有可能確定一個C enum class
的++基數:是否可以確定一個C++枚舉類的元素的數量?
enum class Example { A, B, C, D, E };
我試圖使用sizeof
,但是,它返回一個枚舉元素的大小。
sizeof(Example); // Returns 4 (on my architecture)
是否有一個標準的方法來獲得基數(在我的例子中是5)?
不是直接的,但你可以使用下面的技巧:
enum class Example { A, B, C, D, E, Count };
然後基數可作爲(int)Example::Count
。
當然,如果你讓枚舉的值自動分配,從0開始,這隻會很好地工作。如果不是這種情況,你可以手動分配正確的基數到計數,這實際上沒有什麼不同反正維護單獨的常數:
enum class Example { A = 1, B = 2, C = 4, D = 8, E = 16, Count = 5 };
的一個缺點是,編譯器將允許您使用Example::Count
作爲一個枚舉值的參數 - 如果你使用這個,所以要小心! (儘管我個人發現這在實踐中並不是問題)。
雖然如果任何值被設置爲默認值以外的值,這會中斷。所以,小心使用。 – juanchopanza 2013-02-20 20:31:32
好的謝謝你的提示 – bquenin 2013-02-20 20:31:39
枚舉值在枚舉類中是類型安全的,所以'Count'的類型將是Example,而不是int,對吧?您必須先將「計數」轉換爲int,才能將其用於大小。 – 2015-03-26 13:29:23
不,你必須寫在代碼中。
您可以嘗試的一個技巧是在列表末尾添加一個枚舉值,並將其用作大小。在您的例子
enum class Example { A, B, C, D, E, ExampleCount };
enum class TEST
{
BEGIN = __LINE__
, ONE
, TWO
, NUMBER = __LINE__ - BEGIN - 1
};
auto const TEST_SIZE = TEST::NUMBER;
聰明!當然,不能有任何評論或不尋常的間距,對於真正大的源文件,底層的值類型可能會比其他的更大。 – 2016-09-05 00:46:38
@Kyle Strand:存在這個問題:使用char,你也有超過256個枚舉器。但編譯器有很好的方式來通知你截斷等 __LINE__是一個整數字面值,並使用#line有限制[1,2147483647] – UglyCoder 2016-09-06 18:35:15
啊,好的。儘管如此,即使一個本來是「short」的枚舉可能會碰到「int」,例如當做統一建設。 (雖然我認爲這與統一構建相比是一個問題,但與你提出的技巧相比)。 – 2016-09-06 19:55:26
constexpr auto TEST_START_LINE = __LINE__;
enum class TEST { // Subtract extra lines from TEST_SIZE if an entry takes more than one
ONE = 7
, TWO = 6
, THREE = 9
};
constexpr auto TEST_SIZE = __LINE__ - TEST_START_LINE - 3;
這是從UglyCoder's answer三種方式產生,但它提高。
BEGIN
和SIZE
)沒有多餘的元素(Cameron's answer也有這個問題。)
它保留UglyCoder's優於Cameron's answer的優點是可以爲枚舉器賦予任意值。
一個問題(與UglyCoder共享,但不與Cameron共享)是它使新行和註釋顯着......這是意想不到的。所以有人可以添加一個空格或評論的條目,而不需要調整TEST_SIZE
的計算。
您也可以考慮static_cast<int>(Example::E) + 1
,它消除了額外的元素。
這個答案對於這個特定的編程問題是正確的,但是一般來說遠非優雅和容易出錯。這個枚舉可以在將來用新的值進行擴展,以取代'Example :: E'作爲枚舉中的最後一個值。即使情況並非如此,「Example :: E」的文字值可能會改變。 – Matthias 2017-05-15 14:58:11
有基於X一招() - 宏:圖像,您有以下枚舉:
enum MyEnum {BOX, RECT};
格式化它:
#define MyEnumDef \
X(BOX), \
X(RECT)
然後將下面的代碼定義枚舉類型:
enum MyEnum
{
#define X(val) val
MyEnumDef
#undef X
};
和下面的代碼計算枚舉元素的數目:
template <typename ... T> void null(T...) {}
template <typename ... T>
constexpr size_t countLength(T ... args)
{
null(args...); //kill warnings
return sizeof...(args);
}
constexpr size_t enumLength()
{
#define XValue(val) #val
return countLength(MyEnumDef);
#undef XValue
}
...
std::array<int, enumLength()> some_arr; //enumLength() is compile-time
std::cout << enumLength() << std::endl; //result is: 2
...
我想可能有一個特定的c + + 11機制 – bquenin 2013-02-20 20:32:32
順便說一句,這不是重複的。 'enum'和'enum class''是非常不同的概念。 – Shoe 2013-12-02 02:13:03
@Shoe ......他們真的嗎? – 2016-09-06 19:55:44