在我们使用强枚举时,往往需要生成全枚举的参数包,因此参考STL自己实现了一个:
#include <cstddef>
#include <type_traits>
enum class MyEnum {
ONE,
TWO,
THREE,
SIZE
};
template <auto... N>
struct NumSeq {};
template <typename Enum>
class EnumUtil {
template <auto N> static constexpr size_t SIZE = static_cast<size_t>(N);
template <auto N> static constexpr Enum ENUM = static_cast<Enum>(N);
template <Enum E, Enum... NextE>
struct Helper : Helper<ENUM<SIZE<E> - 1>, ENUM<SIZE<E> - 1>, NextE...> {};
template <Enum... NextE>
struct Helper<ENUM<0>, NextE...> {
using type = NumSeq<NextE...>;
};
public:
using Sequence = typename Helper<Enum::SIZE>::type;
};
template <typename Enum>
using EnumSeq = typename EnumUtil<Enum>::Sequence;
int main(int argc, char* argv[])
{
static_assert(std::is_same_v<EnumSeq<MyEnum>, NumSeq<MyEnum::ONE, MyEnum::TWO, MyEnum::THREE>>);
return 0;
}
有时我们在写库时,涉及类型绑定,稍微扩展也可以使用
#include <cstddef>
#include <type_traits>
#include <tuple>
enum class MyEnum {
ONE,
TWO,
THREE,
SIZE
};
template <typename T>
struct Type {
using type = T;
};
template <auto T>
struct Bind : Type<void> {
};
template <> struct Bind<MyEnum::ONE> : Type<int> {};
template <> struct Bind<MyEnum::TWO> : Type<float> {};
template <> struct Bind<MyEnum::THREE> : Type<char> {};
template <typename Enum>
class EnumUtil {
template <auto N> static constexpr size_t SIZE = static_cast<size_t>(N);
template <auto N> static constexpr Enum ENUM = static_cast<Enum>(N);
template <Enum E, Enum... NextE>
struct Helper : Helper<ENUM<SIZE<E> - 1>, ENUM<SIZE<E> - 1>, NextE...> {};
template <Enum... NextE>
struct Helper<ENUM<0>, NextE...> {
using tuple_type = std::tuple<typename Bind<NextE>::type...>;
};
public:
using Tuple = typename Helper<Enum::SIZE>::tuple_type;
};
template <typename Enum>
using EnumTuple = typename EnumUtil<Enum>::Tuple;
int main(int argc, char* argv[])
{
static_assert(std::is_same_v<EnumTuple<MyEnum>, std::tuple<int, float, char>>);
// 需要注意的是
static_assert(sizeof(std::tuple<int, float, char>) != (sizeof(int) + sizeof(float) + sizeof(char)));
return 0;
}
注意事项
- 当前代码仅兼容C++17