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

如何为可变模板参数类实现存储去重类型的using别名

C++ 模板参数去重并通过using别名获取

要实现模板参数去重并封装到自定义类中,可借助C++模板元编程逐步筛选不重复类型,以下是完整解决方案:

1. 定义TypeSet类

用来持有去重后的类型集合,用tuple包装类型列表方便后续操作:

#include <tuple>
#include <type_traits>

template <typename... Ts>
class TypeSet {
public:
    // 用tuple存储去重后的类型列表
    using type_tuple = std::tuple<Ts...>;

    // 根据索引获取对应类型(默认取第一个元素)
    template <size_t N = 0>
    using type_at = std::tuple_element_t<N, type_tuple>;
};

2. 实现类型去重的元工具

通过辅助结构体逐步构建不重复的类型集合:

// 辅助构建器:负责累加不重复的类型
template <typename... Accumulated>
struct UniqueBuilder {
    // 尝试添加一个类型:如果已存在则不改变集合,否则加入
    template <typename T>
    using add = std::conditional_t<
        (std::is_same_v<T, Accumulated> || ...),
        UniqueBuilder<Accumulated...>,
        UniqueBuilder<Accumulated..., T>
    >;

    // 生成最终的TypeSet类型
    using result = TypeSet<Accumulated...>;
};

// 空的初始构建器
using EmptyUniqueBuilder = UniqueBuilder<>;

// 展开所有输入类型,完成去重逻辑
template <typename... Ts>
struct UniqueTypes {
    // 用折叠表达式依次处理每个输入类型
    using builder = decltype((EmptyUniqueBuilder::template add<Ts>(), ...));
    using type = typename builder::result;
};

// 简化使用的模板别名
template <typename... Ts>
using UniqueTypeSet = typename UniqueTypes<Ts...>::type;

3. 实现return_unique函数(可选)

如果需要通过函数返回TypeSet对象:

template <typename... Ts>
constexpr auto return_unique() {
    return UniqueTypeSet<Ts...>{};
}

4. 在myobj类中引用去重后的类型

直接通过模板别名获取,或通过return_unique的返回类型获取:

template <typename... Ts>
class myobj {
public:
    // 方式1:直接用模板别名获取去重后的TypeSet类型
    using unique_types_set = UniqueTypeSet<Ts...>;
    // 获取去重后的单个类型(适合单类型去重场景)
    using unique_template = typename unique_types_set::template type_at<0>;

    // 方式2:通过return_unique的返回类型获取(与方式1等价)
    using unique_template_via_func = typename decltype(return_unique<Ts...>())::template type_at<0>;
};

测试验证

// 验证去重逻辑正确性
static_assert(std::is_same_v<UniqueTypeSet<int, int>, TypeSet<int>>);
static_assert(std::is_same_v<UniqueTypeSet<int, double, int, float>, TypeSet<int, double, float>>);

// 验证myobj中的类型别名
static_assert(std::is_same_v<myobj<int, int>::unique_template, int>);
static_assert(std::is_same_v<myobj<int, double, int>::unique_types_set, TypeSet<int, double>>);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:23:19