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

C++对std::vector<std::variant>按类型过滤迭代的简化实现咨询

问题解答

问题1解答

可以实现,利用C++20引入的泛型lambda,不需要自定义任何结构体,也不需要编写冗余的类型转换或者全量指定模板参数,示例用法如下:

// 无需自定义任何结构体,直接在循环内写逻辑即可
for (const auto& green : colors 
    | std::views::filter([](const auto& var) { return std::holds_alternative<Green>(var); })
    | std::views::transform([](const auto& var) { return std::get<Green>(var); })) {
    std::cout << green.x << std::endl;
}

如果想封装成可复用的管道适配器,也可以直接用lambda实现,不需要额外定义结构体:

template <typename T>
inline constexpr auto variant_filter = std::views::filter([](const auto& var) {
    return std::holds_alternative<T>(var);
}) | std::views::transform([](const auto& var) -> decltype(auto) {
    return std::get<T>(var);
});

封装后可以直接按你原本的写法调用。

问题2解答

你的代码无法编译是两处细节不匹配导致的:

  • variant_get_t<T>::operator()的入参是非const左值引用,但你重载的operator|接收的输入范围是const R&类型,经过filter视图传递给transform的元素自带const属性,参数类型不匹配。
  • 两个仿函数的operator()都没有加const修饰,C++标准库视图要求传入的可调用对象必须支持const调用,否则无法在视图内部执行调用逻辑。

修复后的代码片段

template <typename T> struct engaged_t {
  template <typename... Ts>
  // 加const修饰符
  constexpr bool operator()(const std::variant<Ts...> &variant) const {
    return std::holds_alternative<T>(variant);
  }
};

template <typename T> struct variant_get_t {
  template <typename... Ts>
  // 入参改为const引用,加const修饰符
  constexpr decltype(auto) operator()(const std::variant<Ts...> &variant) const {
    return std::get<T>(variant);
  }
};

修改后你注释掉的测试代码可以正常编译运行,输出结果为1和1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:54:03