【C++ 元编程】生成枚举参数包

本文展示了如何利用C++17特性自定义模板来创建枚举类的全枚举参数包以及进行类型绑定。通过EnumUtil类模板,可以生成枚举类型的NumSeq和EnumTuple,方便在库中进行类型操作。示例代码中,对MyEnum枚举类进行了演示,验证了类型匹配与大小关系。
摘要由CSDN通过智能技术生成

在我们使用强枚举时,往往需要生成全枚举的参数包,因此参考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;
}

注意事项

  1. 当前代码仅兼容C++17
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值