std::ranges::copy_if需包含和,c++20起可用,要求编译器开启c++20模式;它不修改原容器,仅按谓词筛选元素写入目标范围,目标必须有足够空间或配合std::back_inserter使用。

std::ranges::copy_if 基本用法和必要头文件
必须包含 <algorithm></algorithm> 和 <vector></vector>,C++20 起 std::ranges::copy_if 才可用,且要求编译器开启 C++20 模式(如 g++ -std=c++20)。它不修改原容器,只按谓词筛选元素并写入目标范围——目标必须有足够空间,或配合 std::back_inserter 动态扩展。
目标 vector 为空时怎么填数据
直接传 std::back_inserter(dest_vec) 是最常见也最安全的做法,避免手动预分配大小出错。若提前知道大概数量,也可先 reserve() 提升性能,但 resize() 或直接传 dest_vec.begin() 会触发未定义行为(越界写)。
- ✅ 正确:
std::ranges::copy_if(src, std::back_inserter(dest), pred) - ⚠️ 高风险:
dest.resize(n); std::ranges::copy_if(src, dest.begin(), pred)(n 估算不准就溢出) - ❌ 错误:
std::ranges::copy_if(src, dest.begin(), pred)(dest 为空,begin()不可写)
谓词写法与常见陷阱
谓词必须是可调用对象,接受一个参数并返回 bool;捕获局部变量时注意生命周期——若源数据是临时对象(如函数返回的 std::vector),而谓词里又存了引用,运行时可能崩溃。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
std::vector<int> nums = {1, 2, 3, 4, 5, 6};
std::vector<int> evens;
// ✅ 安全:值捕获或无捕获
std::ranges::copy_if(nums, std::back_inserter(evens), [](int x) { return x % 2 == 0; });
// ⚠️ 危险:若 nums 是临时量,&nums 会悬垂
auto pred_ref = [&nums](int x) { return x > nums[0]; }; // 不要这样用
</int></int>
和传统 std::copy_if 的关键区别
老式 std::copy_if 要求传入输出迭代器,且不检查目标容量;std::ranges::copy_if 支持范围(range)语义,更直观,但底层仍依赖迭代器——它不会自动扩容容器,只是把“写入位置”抽象成范围概念。真正实现动态追加的,仍是 std::back_inserter 这个适配器,不是 ranges 本身的功能。
-
std::copy_if:三迭代器接口,易写错终点 -
std::ranges::copy_if:输入范围 + 输出范围 + 谓词,语义清晰,但输出范围仍需可写且有效 - 两者性能无本质差异,选哪个主要看代码风格和 C++ 标准支持情况
最容易被忽略的是:哪怕用了 std::ranges,你依然得自己管好目标容器的内存——back_inserter 不是魔法,它只是帮你调 push_back;如果目标是固定大小数组或 stack 分配的 buffer,那必须确保长度足够,否则行为未定义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










