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

C++如何用谓词提取struct vector子集生成对应指针vector?

实现方案

C++ 标准库没有提供单步完成「筛选+转换」的独立算法,但可以通过现有标准组件组合实现,以下是两种常用的声明式实现方案:

C++20 范围库方案(最符合声明式需求)

C++20 引入的范围库可以直接组合过滤、转换操作,代码可读性最高,完全不需要手动控制遍历、插入逻辑:

#include <vector>
#include <ranges>

typedef struct {
    int a;
    char b;
} some_struct_t;

int main()
{
    std::vector<some_struct_t> v = { {10, '1'}, {5, '2'} };
    // 先过滤符合条件的元素,再逐个取地址,最后转为指针vector
    auto v2 = v | std::views::filter([](const some_struct_t& s) { return s.a == 5; })
                | std::views::transform([](some_struct_t& s) { return &s; })
                | std::ranges::to<std::vector<some_struct_t*>>();
}

C11~C17 兼容方案

如果用不了 C++20,可以用std::for_each实现,逻辑清晰无额外依赖:

#include <vector>
#include <algorithm>

typedef struct {
    int a;
    char b;
} some_struct_t;

int main()
{
    std::vector<some_struct_t> v = { {10, '1'}, {5, '2'} };
    std::vector<some_struct_t*> v2;
    v2.reserve(v.size()); // 预先分配空间优化性能

    std::for_each(v.begin(), v.end(), [&v2](some_struct_t& s) {
        if (s.a == 5) {
            v2.push_back(&s);
        }
    });
}

如果需要可复用的泛用算法,也可以自行封装符合你需求的模板函数:

template <typename InputIt, typename OutputIt, typename Pred, typename Transform>
void filter_transform(InputIt first, InputIt last, OutputIt d_first, Pred pred, Transform trans) {
    for (; first != last; ++first) {
        if (pred(*first)) {
            *d_first++ = trans(*first);
        }
    }
}

// 调用示例
filter_transform(v.begin(), v.end(), std::back_inserter(v2),
    [](const some_struct_t& s) { return s.a == 5; },
    [](some_struct_t& s) { return &s; }
);

注意事项

  • 你保存的是原 vector 元素的裸指针,需要保证原 vector 的生命周期长于指针 vector v2,且原 vector 没有发生元素增删导致的内存重分配,否则指针会悬空引发未定义行为。
  • 如果需要指针和原元素的生命周期绑定,可以考虑使用std::shared_ptr/std::unique_ptr存储原 vector 元素,或者改用下标索引代替裸指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:09:01