如何将可变参数类型的内部类型转为可变参数传入模板类?
实现思路与代码示例
核心思路拆解
要实现类E中DT的定义,需要完成三个关键步骤:
- 提取所有
As成员中的BT和CT类型,合并为一个完整的类型集合 - 对该类型集合进行去重处理,确保每个类型仅出现一次
- 将去重后的类型集合作为模板参数传递给
D,生成目标类型
完整实现代码
首先补充原代码中缺失的空参数包特化(避免D<>时的约束错误):
#include <tuple> #include <type_traits> // 原有的is_unique_v,补充空参数包特化 template<class T, class... Ts> constexpr bool is_unique_v = (!std::is_same_v<T, Ts> && ...) && is_unique_v<Ts...>; template<class T> constexpr bool is_unique_v<T> = true; template<> constexpr bool is_unique_v<> = true; // 空参数包默认唯一 // 原有的A类定义(修正访问权限) template<class B, class C> class A { public: using BT = B; using CT = C; }; // 原有的D类定义 template<class... BorCs> requires is_unique_v<BorCs...> class D { public: using UT = std::tuple<BorCs...>; }; // 辅助工具1:判断类型是否存在于tuple中 template<typename U, typename Tuple> struct tuple_contains; template<typename U, typename... Us> struct tuple_contains<U, std::tuple<Us...>> : std::disjunction<std::is_same<U, Us>...> {}; template<typename U, typename Tuple> constexpr bool tuple_contains_v = tuple_contains<U, Tuple>::value; // 辅助工具2:对tuple中的类型进行去重 template<typename Tuple> struct unique_types; template<> struct unique_types<std::tuple<>> { using type = std::tuple<>; }; template<typename T, typename... Ts> struct unique_types<std::tuple<T, Ts...>> { private: using rest_unique = typename unique_types<std::tuple<Ts...>>::type; public: using type = std::conditional_t< tuple_contains_v<T, rest_unique>, rest_unique, decltype(std::tuple_cat(std::tuple<T>(), rest_unique)) >; }; template<typename Tuple> using unique_types_t = typename unique_types<Tuple>::type; // 辅助工具3:将tuple类型转换为D的实例 template<typename Tuple> struct D_from_tuple; template<typename... Ts> struct D_from_tuple<std::tuple<Ts...>> { using type = D<Ts...>; }; template<typename Tuple> using D_from_tuple_t = typename D_from_tuple<Tuple>::type; // 最终实现的E类 template<class... As> class E { // 步骤1:收集所有As的BT和CT到tuple中 using collected_types = std::tuple<typename As::BT..., typename As::CT...>; // 步骤2:对收集到的类型去重 using unique_collected = unique_types_t<collected_types>; // 步骤3:转换为D类型 public: using DT = D_from_tuple_t<unique_collected>; };
关键细节说明
- 访问权限修正:原
A类中的BT和CT需要设为public,否则E无法访问这些嵌套类型。 - 空参数包处理:补充
is_unique_v<>的特化,确保当没有As传入时,D<>能满足约束。 - 类型去重逻辑:通过递归遍历类型列表,检查当前类型是否已存在于去重后的剩余列表中,不存在则加入,最终得到唯一类型集合。
- 类型转换:借助
D_from_tuple将去重后的tuple类型展开为D的模板参数包,生成目标DT类型。
内容的提问来源于stack exchange,提问作者SpeakX
相关产品推荐
相关产品推荐

