如何在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;
代码解释
- 主模板与递归展开:通过可变参数模板递归处理每一组
bool-类型对,利用std::conditional_t在编译期判断当前条件是否成立,成立则返回对应类型,否则继续递归处理剩余参数。 - 奇数参数处理:最后一个参数作为默认 fallback 类型,当所有条件都不满足时,递归终止到仅含该类型的特化,直接返回它。
- 偶数参数处理:用C++20的
requires约束确保剩余参数中布尔值和类型的数量相等(即保持成对),当所有条件都不满足时,会匹配到空参数的特化,触发static_assert抛出编译错误。 - 辅助别名:
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
相关产品推荐
相关产品推荐

