如何让std::find_if返回所有匹配结果,实现类似正则的贪婪匹配?
如何用std::find_if获取所有匹配结果?
我需要筛选出所有大于3的数值,自己实现的ForEach函数能输出预期的5 6:
void ForEach(const std::vector<int> &values, void (*fun_ptr)(int)) { for (int v : values) if (v > 3) fun_ptr(v); } int main() { std::vector<int> values = {1, 5, 6, 2, 3}; auto lambd = [](int v) { printf("%d ", v); }; ForEach(values, lambd); return 0; }
但用std::find_if的代码只能返回首个匹配项5:
int main() { std::vector<int> values = {1, 5, 6, 2, 3}; auto it = std::find_if(values.begin(), values.end(), [](int v){return v>3;}); printf("%d ", *it); return 0; }
怎么让std::find_if返回所有匹配结果,实现类似贪婪匹配的效果?
解决方法
1. 循环调用std::find_if遍历所有匹配项
std::find_if本身只负责定位第一个符合条件的元素,要获取所有结果,只需在找到首个匹配项后,从该元素的下一个位置继续调用std::find_if,直到遍历完整个容器:
#include <vector> #include <algorithm> #include <cstdio> int main() { std::vector<int> values = {1, 5, 6, 2, 3}; auto it = values.begin(); while ((it = std::find_if(it, values.end(), [](int v){return v>3;})) != values.end()) { printf("%d ", *it); ++it; // 移动到下一个位置,避免重复匹配当前元素 } return 0; }
运行后输出5 6,和自定义ForEach的效果一致。
2. 用std::copy_if收集结果到新容器
如果需要把所有匹配元素保存下来后续使用,std::copy_if是更合适的选择,它会自动将符合条件的元素复制到目标容器:
#include <vector> #include <algorithm> #include <cstdio> int main() { std::vector<int> values = {1, 5, 6, 2, 3}; std::vector<int> results; std::copy_if(values.begin(), values.end(), std::back_inserter(results), [](int v){return v>3;}); // 遍历输出结果 for (int v : results) { printf("%d ", v); } return 0; }
3. 用std::for_each直接处理匹配元素
你自定义的ForEach逻辑和标准库的std::for_each高度相似,结合lambda的条件判断就能直接处理所有匹配元素,写法更简洁:
#include <vector> #include <algorithm> #include <cstdio> int main() { std::vector<int> values = {1, 5, 6, 2, 3}; std::for_each(values.begin(), values.end(), [](int v){ if (v > 3) printf("%d ", v); }); return 0; }
关键说明
std::find_if的设计初衷就是找到第一个满足条件的元素,没有直接返回所有匹配项的重载,必须通过循环迭代实现批量查找。如果只是需要遍历处理匹配元素,std::for_each加条件判断的写法最直观;如果需要留存结果,std::copy_if的效率更高。
内容的提问来源于stack exchange,提问作者singularli
相关产品推荐
相关产品推荐

