是否有可能确定一个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 };
然后基数是可作为(int)Example::Count
。
当然,这只是工作得很好,如果你让枚举值是自动分配的,从0开始如果不是的话,你可以手动分配正确的基数来算,这是需要维护一个独立的恒定真的没有什么不同无论如何:
enum class Example { A = 1, B = 2, C = 4, D = 8, E = 16, Count = 5 };
一个缺点是,编译器将允许您使用Example::Count
作为一个枚举值的参数-如果你使用这个,所以要小心! (我个人觉得这不是在实践中的问题,虽然)。
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的答案 ,但它提高了在三个方面。
BEGIN
和SIZE
)( 卡梅隆的回答也有这个问题。) 它保留UglyCoder的超过优势卡梅隆的回答是普查员可以指定任意值。
一个问题(共享UglyCoder但不与卡梅伦 )是,它使新行和评论显著......这是意想不到的。 因此,有人可能会增加与空白条目或不调整注释TEST_SIZE
的计算。
enum class TEST
{
BEGIN = __LINE__
, ONE
, TWO
, NUMBER = __LINE__ - BEGIN - 1
};
auto const TEST_SIZE = TEST::NUMBER;
// or this might be better
constexpr int COUNTER(int val, int )
{
return val;
}
constexpr int E_START{__COUNTER__};
enum class E
{
ONE = COUNTER(90, __COUNTER__) , TWO = COUNTER(1990, __COUNTER__)
};
template<typename T>
constexpr T E_SIZE = __COUNTER__ - E_START - 1;
一个窍门,你可以尝试是在列表的末尾添加一个枚举值,并用其作为大小。 在你的榜样
enum class Example { A, B, C, D, E, ExampleCount };
不,你必须把它写在代码中。
有基于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 ++ 17可以使用magic_enum :: enum_count从LIB https://github.com/Neargye/magic_enum magic_enum :: enum_count() - > 4。
还可以考虑static_cast<int>(Example::E) + 1
,它消除了额外的元件。
如果你使用的升压转换器的预处理工具,您可以获取使用count BOOST_PP_SEQ_SIZE(...)
例如,一个可以定义CREATE_ENUM
如下宏:
#include <boost/preprocessor.hpp>
#define ENUM_PRIMITIVE_TYPE std::int32_t
#define CREATE_ENUM(EnumType, enumValSeq) \
enum class EnumType : ENUM_PRIMITIVE_TYPE \
{ \
BOOST_PP_SEQ_ENUM(enumValSeq) \
}; \
static constexpr ENUM_PRIMITIVE_TYPE EnumType##Count = \
BOOST_PP_SEQ_SIZE(enumValSeq); \
// END MACRO
然后,调用宏:
CREATE_ENUM(Example, (A)(B)(C)(D)(E));
会生成以下代码:
enum class Example : std::int32_t
{
A, B, C, D, E
};
static constexpr std::int32_t ExampleCount = 5;
这仅与问候到升压预处理器工具划伤表面。 例如,您的宏还可以从字符串转换工具和ostream的操作符强类型枚举定义为/。
更多关于这里升压预处理器工具: https://www.boost.org/doc/libs/1_70_0/libs/preprocessor/doc/AppendixA-AnIntroductiontoPreprocessorMetaprogramming.html
顺便说一句,我碰巧与@FantasticMrFox强烈同意,额外的Count
,如果使用中公认的答案使用枚举值会产生编译器警告头痛嘉豪switch
语句。 我发现unhandled case
编译器警告代码更安全的维护是非常有用的,所以我不想破坏它。