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

使用std::for_each()和std::bind()过滤vector元素存入新vector失效问题

问题根因

问题出在std::bind的默认参数传递逻辑:

  • std::bind会对所有非占位符的传入参数做值拷贝,你写的bind(mypred, placeholders::_1, 3, final)会直接复制一份final向量生成临时副本,后续mypred函数里对参数c的所有修改(包括push_back插入元素)全都是在这个临时副本上操作的。
  • for_each执行完成后,这个临时副本会立刻销毁,main函数里定义的原始final向量从头到尾没有被修改过,自然是空的。
  • 你能看到两次yes打印,是因为1、2两个元素确实满足a < 3的判断条件,打印逻辑正常执行了,只是插入的元素全留在了被销毁的临时副本里,没有同步到原向量。
修复方案

要让bind持有原向量的引用而不是拷贝副本,只需要用std::ref()把传入的final包裹起来即可,修正后的完整代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // 提供std::bind、std::ref、占位符支持

using namespace std;

void mypred(int a, int b, vector<int>& c){
    if(a < b){
        cout <<"yes" << endl;
        c.push_back(a);
    }
}

int main(){
    vector<int> test = {1,2,3,4,5,6,7};
    vector<int> final;
    final.reserve(10);
    // 用std::ref包装final,强制按引用传递原向量
    for_each(test.begin(), test.end(), bind(mypred, placeholders::_1, 3, ref(final)));
    for(auto i = final.begin(); i != final.end(); i++){
        cout << *i << endl;
    }

    return 0;
}

运行修正后的代码,会正常打印两次yes,最终遍历final时能正确输出1、2两个元素。

如果是写现代C++(C++11及以后版本),更推荐直接用lambda替代std::bind,不需要记特殊的传参规则,捕获逻辑更直观,不容易出类似的拷贝问题:

// 替换原来的for_each行即可
for_each(test.begin(), test.end(), [&final](int a) {
    if (a < 3) {
        cout << "yes" << endl;
        final.push_back(a);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:39:08