如何为可变模板参数类实现存储去重类型的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
相关产品推荐
相关产品推荐

