我能够定义一个宏,该宏定义了一个老式的枚举,并且GetCount()方法返回了枚举元素的数量:
#define DEFINE_FLAGS_ENUM(EnumName, ...) \
struct EnumName { \
enum { __VA_ARGS__ }; \
static constexpr std::size_t GetCount() { return std::max({__VA_ARGS__}) + 1;} \
};
使用枚举类,我的第一个想法是:
template <class T> struct EnumTraits;
#define NDA_FLAGS_ENUM(EnumName, ...) \
enum class EnumName { __VA_ARGS__ }; \
template<> struct EnumTraits<EnumName> { static constexpr std::size_t GetCount() { return std::max({__VA_ARGS__}) + 1; }};
但这不能编译,因为 VA_ARGS 应该以'EnumName ::'开头。
答案 0 :(得分:2)
枚举
如注释中所建议,至于您的第一个宏DEFINE_FLAGS_ENUM
,std::max
似乎无效。
因此,我提出了另一种方法。
由于我们的enum
在类EnumName
中被定义为匿名变量,因此我们可以定义它们的元组并在编译时检测其大小,如下所示。
因此,此宏非常适合您:
#include <tuple>
#define DEFINE_FLAGS_ENUM(EnumName, ...) \
struct EnumName \
{ \
enum { __VA_ARGS__ }; \
\
static constexpr std::size_t GetCount() \
{ \
using T = decltype(std::make_tuple(__VA_ARGS__)); \
return std::tuple_size<T>::value; \
} \
};
枚举类
对于enum class
,我们可以按以下方式重新使用上述方法。
在这里,我们不计算枚举类的元素,而是再次将作为私有成员隐藏在类EnumTraits<EnumName>
中的 enum 进行计数:
#include <tuple>
template <class T> struct EnumTraits;
#define NDA_FLAGS_ENUM(EnumName, ...) \
enum class EnumName { __VA_ARGS__ }; \
template<> \
struct EnumTraits<EnumName> \
{ \
private: \
enum { __VA_ARGS__ }; \
\
public: \
static constexpr std::size_t GetCount() \
{ \
using T = decltype(std::make_tuple(__VA_ARGS__)); \
return std::tuple_size<T>::value; \
} \
};
然后我们可以定义一个枚举和枚举类,如下所示:
// enum.
DEFINE_FLAGS_ENUM(Animal, Dog, Cat)
static_assert(Animal::GetCount() == 2);
// enum class.
NDA_FLAGS_ENUM(Vehicle, Car, Train, AirPlain)
static_assert(EnumTraits<Vehicle>::GetCount() == 3);