You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制嵌套模板参数类型(不使用C++20特性)

解决方案:限制模板类参数的枚举类型匹配

要实现c1<T1, T2>中,若T2是c2<EnumVal>的实例,则EnumVal必须属于T1类型的枚举,同时允许T2为其他任意类型,可以通过类型特性提取+静态断言的方式实现,兼容C17及更早标准(无需C20特性)。

完整实现代码

#include <type_traits>

enum class e1 : size_t {
    a,
    b
};
enum class e2 : size_t {
    a,
    b
};

// 模板类c2:接收任意枚举值作为模板参数
template <auto EnumVal>
struct c2 {
};

// 类型特性:判断是否为c2的实例
template <typename T>
struct is_c2 : std::false_type {};

template <auto EnumVal>
struct is_c2<c2<EnumVal>> : std::true_type {};

template <typename T>
constexpr bool is_c2_v = is_c2<T>::value;

// 类型特性:从c2实例中提取枚举类型和值
template <typename>
struct c2_traits;

template <auto EnumVal>
struct c2_traits<c2<EnumVal>> {
    using enum_type = decltype(EnumVal);
    static constexpr auto enum_value = EnumVal;
};

// 模板类c1:添加静态断言限制枚举类型匹配
template <typename T1, typename T2>
struct c1 {
    // 仅当T2是c2实例时,检查枚举类型是否与T1一致
    static_assert(!is_c2_v<T2> || std::is_same_v<typename c2_traits<T2>::enum_type, T1>,
                  "错误:c2的枚举值类型必须与c1的第一个模板参数匹配");
};

// 测试案例
c1<e1, c2<e1::a>> o1; // 编译通过
// c1<e1, c2<e2::a>> o2; // 编译报错:触发静态断言
// c1<int, float> o3; // 编译通过(T2为非c2类型,不受限制)

核心逻辑说明

  1. c2的定义:使用非类型模板参数auto接收任意枚举值(若需兼容C++11/14,可改为typename EnumType, EnumType EnumVal的显式参数形式)。
  2. is_c2特性:用于判断T2是否为c2的实例,避免对非c2类型进行不必要的检查。
  3. c2_traits特性:从c2<EnumVal>实例中提取枚举值的类型enum_type,为后续匹配检查提供依据。
  4. c1的静态断言:仅当T2是c2实例时,才强制检查其枚举类型是否与c1的第一个参数T1一致,满足“T2可以是其他类型”的需求。

内容的提问来源于stack exchange,提问作者Graznarak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 01:22:22