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

如何将可变参数类型的内部类型转为可变参数传入模板类?

实现思路与代码示例

核心思路拆解

要实现类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>;
};

关键细节说明

  1. 访问权限修正:原A类中的BT和CT需要设为public,否则E无法访问这些嵌套类型。
  2. 空参数包处理:补充is_unique_v<>的特化,确保当没有As传入时,D<>能满足约束。
  3. 类型去重逻辑:通过递归遍历类型列表,检查当前类型是否已存在于去重后的剩余列表中,不存在则加入,最终得到唯一类型集合。
  4. 类型转换:借助D_from_tuple将去重后的tuple类型展开为D的模板参数包,生成目标DT类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:47:42