C++ Boost::bind出现调用匹配失败与模板参数推导替换错误问题
问题原因及修复方案
1 直接编译报错的根因
你的编译错误由两个基础语法问题触发:
std::vector::emplace方法第一个入参要求是插入位置的迭代器,如果你需要在容器末尾追加构造线程对象,应该调用emplace_back而非emplace,这是报错的直接诱因。- 线程容器类型混乱:你声明的是
std::vector<std::thread>,但报错显示编译器识别容器元素为boost::thread,建议统一线程库实现,要么全用C++标准库的std::thread,要么全用boost::thread,避免类型不匹配。
2 必须修正的逻辑错误
即使编译通过,你的代码也无法得到预期结果,存在几个核心逻辑问题:
- 参数传递规则错误:你当前
function的vector、list、results都是值传递,线程内修改的是参数副本,主线程的results完全不会被更新。需要将只读参数改为const&,需要回写结果的results改为&,修正后的函数签名如下:
void function(size_t thread, size_t start_index, size_t sub_length, const std::vector<double>& index_vec, double** array, const std::vector<std::string>& list, std::vector<double>& results)
提示:参数名不要用vector,和标准库类型重名容易引发意料之外的编译问题
- 分片逻辑错误:你当前
start_index = i * sub_length写在创建线程的循环外部,所有线程拿到的起始索引完全一致,会重复处理同一段数据,需要把这行逻辑放到创建线程的for循环内部。 - bind传引用必须包裹:给bind传递引用参数时,必须用
std::ref(对应std::thread)或者boost::ref(对应boost::thread)包裹,否则bind仍会对参数做拷贝,达不到传引用的效果。
3 修正后的核心代码示例
标准库线程实现(无需boost::bind)
std::vector<std::thread> threads; // 其余变量初始化逻辑不变 size_t sub_length = 500 / num_threads; for (size_t i = 0; i < num_threads; i++) { size_t start_index = i * sub_length; // 最后一个线程处理剩余的所有数据,避免总长度不是线程数整数倍时越界 size_t current_sub_len = (i == num_threads -1) ? (500 - start_index) : sub_length; // 只读参数用std::cref包裹,可写参数用std::ref包裹 threads.emplace_back(function, i, start_index, current_sub_len, std::cref(vector), array, std::cref(list), std::ref(results)); } for (auto& th : threads) { th.join(); }
保留boost::bind的写法
// 线程容器统一用boost::thread std::vector<boost::thread> threads; for (size_t i = 0; i < num_threads; i++) { size_t start_index = i * sub_length; size_t current_sub_len = (i == num_threads -1) ? (500 - start_index) : sub_length; threads.emplace_back(boost::bind(function, i, start_index, current_sub_len, boost::cref(vector), array, boost::cref(list), boost::ref(results))); }
内容的提问来源于stack exchange,提问作者magus_e
相关产品推荐
相关产品推荐

