我能够定义定义旧式枚举和返回枚举元素计数的 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::"为前缀。
正如评论中所建议的,至于您的第一个宏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>
中的枚举元素计算为私有成员:
#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);