Is it possible to determine the cardinality of a c++ enum class
:
enum class Example { A, B, C, D, E };
I tried to use sizeof
, however, it returns the size of an enum element.
sizeof(Example); // Returns 4 (on my architecture)
Is there a standard way to get the cardinality (5 in my example) ?
Use the len() class to get the number of elements in an enum, e.g. len(Color) . The len() function returns the length (the number of items) of an object and can directly be passed an enum. Copied! The len() function returns the length (the number of items) of an object.
Numeric enums are number-based enums i.e. they store string values as numbers. Enums are always assigned numeric values when they are stored. The first value always takes the numeric value of 0, while the other values in the enum are incremented by 1.
On an 8-bit processor, enums can be 16-bits wide. On a 32-bit processor they can be 32-bits wide or more or less.
Not directly, but you could use the following trick:
enum class Example { A, B, C, D, E, Count };
Then the cardinality is available as static_cast<int>(Example::Count)
.
Of course, this only works nicely if you let values of the enum be automatically assigned, starting from 0. If that's not the case, you can manually assign the correct cardinality to Count, which is really no different from having to maintain a separate constant anyway:
enum class Example { A = 1, B = 2, C = 4, D = 8, E = 16, Count = 5 };
The one disadvantage is that the compiler will allow you to use Example::Count
as an argument for an enum value -- so be careful if you use this! (I personally find this not to be a problem in practice, though.)
For C++17 you can use magic_enum::enum_count
from lib https://github.com/Neargye/magic_enum:
magic_enum::enum_count<Example>()
-> 4.
This library uses a compiler-specific hack (based on __PRETTY_FUNCTION__
/ __FUNCSIG__
), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 9.
We go through the given interval range, and find all the enumerations with a name, this will be their count. Read more about limitations
Many more about this hack in this post https://taylorconor.com/blog/enum-reflection.
// clang-format off
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;
// clang-format on
This is derived from UglyCoder's answer but improves it in three ways.
BEGIN
and SIZE
) (Cameron's answer also has this problem.)
It retains UglyCoder's advantage over Cameron's answer that enumerators can be assigned arbitrary values.
A problem (shared with UglyCoder but not with Cameron) is that it makes newlines and comments significant ... which is unexpected. So someone could add an entry with whitespace or a comment without adjusting TEST_SIZE
's calculation. This means that code formatters can break this. After evg656e's comment, I edited the answer to disable clang-format
, but caveat emptor if you use a different formatter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With