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

如何在C++20中实现type_chooser类型选择器 trait

C++20实现type_chooser类型选择器Trait

需求说明

需要实现一个type_chooser类型Trait,支持两种使用场景:

  • 奇数个参数:type_chooser<bool1, T1, bool2, T2, ..., boolN, TN, Telse>,逻辑等价于依次判断每个布尔条件,返回第一个为true对应的类型;若所有条件都为false,则返回最后的Telse。
  • 偶数个参数:type_chooser<bool1, T1, bool2, T2, ..., boolN, TN>,逻辑同上,但如果所有条件都为false,直接触发编译错误。

实现代码

#include <type_traits>

// 主模板声明
template<bool... Bs, typename... Ts>
struct type_chooser;

// 处理带默认 fallback 类型的情况(奇数参数)
template<bool B, typename T, bool... Bs, typename... Ts>
struct type_chooser<B, T, Bs..., Ts...> {
    using type = std::conditional_t<B, T, typename type_chooser<Bs..., Ts...>::type>;
};

// 递归终止:只剩默认 fallback 类型
template<typename Telse>
struct type_chooser<Telse> {
    using type = Telse;
};

// 处理无默认 fallback 的情况(偶数参数),用requires约束保证参数成对
template<bool B, typename T, bool... Bs, typename... Ts>
requires (sizeof...(Bs) == sizeof...(Ts))
struct type_chooser<B, T, Bs..., Ts...> {
    using type = std::conditional_t<B, T, typename type_chooser<Bs..., Ts...>::type>;
};

// 递归终止:无默认类型且所有条件不满足,触发编译错误
template<>
struct type_chooser<> {
    static_assert(false, "type_chooser: 所有条件均为false且未提供默认类型");
    using type = void; // 占位类型,实际不会被使用
};

// 辅助别名,简化使用
template<typename... Args>
using type_chooser_t = typename type_chooser<Args...>::type;

代码解释

  1. 主模板与递归展开:通过可变参数模板递归处理每一组bool-类型对,利用std::conditional_t在编译期判断当前条件是否成立,成立则返回对应类型,否则继续递归处理剩余参数。
  2. 奇数参数处理:最后一个参数作为默认 fallback 类型,当所有条件都不满足时,递归终止到仅含该类型的特化,直接返回它。
  3. 偶数参数处理:用C++20的requires约束确保剩余参数中布尔值和类型的数量相等(即保持成对),当所有条件都不满足时,会匹配到空参数的特化,触发static_assert抛出编译错误。
  4. 辅助别名:type_chooser_t避免了每次使用时都要写typename ...::type,简化代码书写。

使用示例

// 示例1:带默认类型的情况
using T1 = type_chooser_t<false, int, true, double, float>;
// T1 为 double(第二个条件为true,直接返回)

using T2 = type_chooser_t<false, int, false, double, float>;
// T2 为 float(所有条件不满足,取默认类型)

// 示例2:无默认类型的情况
using T3 = type_chooser_t<false, int, true, double>;
// T3 为 double(第二个条件为true)

// 以下代码会触发编译错误:所有条件不满足且无默认类型
// using T4 = type_chooser_t<false, int, false, double>;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:11:17