c++ のカーディナリティを判断することは可能ですかenum class
:
enum class Example { A, B, C, D, E };
を使用しようとしましたsizeof
が、列挙型要素のサイズを返します。
sizeof(Example); // Returns 4 (on my architecture)
カーディナリティ (私の例では 5) を取得する標準的な方法はありますか?
c++ のカーディナリティを判断することは可能ですかenum class
:
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 };
その後、カーディナリティは として利用できますstatic_cast<int>(Example::Count)
。
もちろん、これは enum の値が 0 から始まるように自動的に割り当てられるようにする場合にのみうまく機能します。そうでない場合は、Count に正しいカーディナリティを手動で割り当てることができます。これは、別の定数を維持する必要があるのとまったく同じです。とりあえず:
enum class Example { A = 1, B = 2, C = 4, D = 8, E = 16, Count = 5 };
1 つの欠点は、コンパイラがExample::Count
enum 値の引数として使用できることです。これを使用する場合は注意してください。(個人的には、これは実際には問題ではないと思います。)
std::initializer_list を使用したトリックで解決できます。
#define TypedEnum(Name, Type, ...) \
struct Name { \
enum : Type{ \
__VA_ARGS__ \
}; \
static inline const size_t count = []{ \
static Type __VA_ARGS__; return std::size({__VA_ARGS__}); \
}(); \
};
使用法:
#define Enum(Name, ...) TypedEnum(Name, int, _VA_ARGS_)
Enum(FakeEnum, A = 1, B = 0, C)
int main()
{
std::cout << FakeEnum::A << std::endl
<< FakeEnun::count << std::endl;
}
リストの最後に列挙型の値を追加し、それをサイズとして使用するという方法があります。あなたの例では
enum class Example { A, B, C, D, E, ExampleCount };
行数やテンプレートに依存しない別の方法があります。唯一の要件は、列挙値を独自のファイルに貼り付け、プリプロセッサ/コンパイラに次のようにカウントさせることです。
my_enum_inc.h
ENUMVAL(BANANA)
ENUMVAL(ORANGE=10)
ENUMVAL(KIWI)
...
#undef ENUMVAL
my_enum.h
typedef enum {
#define ENUMVAL(TYPE) TYPE,
#include "my_enum_inc.h"
} Fruits;
#define ENUMVAL(TYPE) +1
const size_t num_fruits =
#include "my_enum_inc.h"
;
これにより、列挙値にコメントを付けたり、値を再割り当てしたり、コードで無視/考慮する必要がある無効な「カウント」列挙値を挿入したりできなくなります。
コメントを気にしない場合は、追加のファイルは必要なく、上記の誰かのように行うことができます。
#define MY_ENUM_LIST \
ENUMVAL(BANANA) \
ENUMVAL(ORANGE = 7) \
ENUMVAL(KIWI)
#include "my_enum_inc.h"
ディレクティブを MY_ENUM_LISTに置き換えますが#undef ENUMVAL
、使用するたびに必要になります。
いいえ、コードに記述する必要があります。
static_cast<int>(Example::E) + 1
余分な要素を削除することも検討できます。