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

C++17如何从Filter类型列表提取去重替换void的std::variant类型

C++17 实现方案

我们通过三个独立的模板元函数逐步完成需求,所有语法均符合C++17标准:

第一步:实现类型转换元函数

负责提取Filter的内部类型,同时将void替换为std::monostate:

#include <variant>
#include <type_traits>

// 单个类型转换:void替换为std::monostate
template <typename T>
struct FilterTypeTransform {
    using type = T;
};
template <>
struct FilterTypeTransform<void> {
    using type = std::monostate;
};
template <typename T>
using FilterTypeTransform_t = typename FilterTypeTransform<T>::type;

第二步:实现类型列表去重元函数

对转换后的类型列表做去重处理,保留类型第一次出现的顺序:

// 辅助工具:给variant的类型列表头部插入新类型
template <typename V, typename T>
struct VariantPushFront;
template <typename... Ts, typename T>
struct VariantPushFront<std::variant<Ts...>, T> {
    using type = std::variant<T, Ts...>;
};
template <typename V, typename T>
using VariantPushFront_t = typename VariantPushFront<V, T>::type;

// 辅助工具:检查类型是否存在于variant的可选类型中
template <typename V, typename U>
struct TypeInVariant : std::false_type {};
template <typename U, typename... Vs>
struct TypeInVariant<std::variant<Vs...>, U> : std::disjunction<std::is_same<U, Vs>...> {};

// 类型去重元函数
template <typename... Ts>
struct UniqueTypes;

// 空列表边界处理
template <>
struct UniqueTypes<> {
    using type = std::variant<>;
};

// 递归处理逻辑
template <typename T, typename... Rest>
struct UniqueTypes<T, Rest...> {
private:
    using UniqueRest = typename UniqueTypes<Rest...>::type;
public:
    using type = std::conditional_t<
        TypeInVariant<UniqueRest, T>::value,
        UniqueRest,
        VariantPushFront_t<UniqueRest, T>
    >;
};
template <typename... Ts>
using UniqueTypes_t = typename UniqueTypes<Ts...>::type;

第三步:整合到Pipeline类

将上述元函数组合,生成最终的variant类型:

template <typename T>
struct Filter {
    using type = T;
};

template <typename... Filters>
struct Pipeline {
    // 最终生成的去重、转换后的variant类型
    using BufferType = UniqueTypes_t<FilterTypeTransform_t<typename Filters::type>...>;
    BufferType buffer;
};

功能验证

通过静态断言验证三个需求全部满足:

#include <string>

// 验证需求1:正常提取Filter内部类型
static_assert(std::is_same_v<
    Pipeline<Filter<int>, Filter<double>, Filter<std::string>>::BufferType,
    std::variant<int, double, std::string>
>);

// 验证需求2:自动去重重复类型
static_assert(std::is_same_v<
    Pipeline<Filter<int>, Filter<double>, Filter<std::string>, Filter<int>>::BufferType,
    std::variant<int, double, std::string>
>);

// 验证需求3:void替换为std::monostate且去重
static_assert(std::is_same_v<
    Pipeline<Filter<int>, Filter<double>, Filter<void>, Filter<int>, Filter<void>>::BufferType,
    std::variant<int, double, std::monostate>
>);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:27:03