调用ThreadPool的enqueue函数报错:no matching member function for call to 'enqueue'
调用ThreadPool的enqueue函数报错:no matching member function for call to 'enqueue'
嘿,我来帮你排查这个问题~ 编译器报的这个错本质是参数类型不匹配,咱们一步步拆解来看:
问题根源
你定义的sum_plus_one lambda,第二个参数是const std::vector<uint64_t> &M(常量引用类型),但你调用TP.enqueue的时候,传的是&M——这是一个std::vector<uint64_t>*指针类型。lambda期望接收引用,你却传了指针,编译器找不到能匹配这个参数组合的enqueue重载,所以就抛出了这个错误。
两种修正方案
你可以根据自己的编码习惯选其中一种:
方案1:修改lambda的参数为指针类型
既然你传的是指针,那直接把lambda的第二个参数改成指针,内部解引用使用即可:
// 调整lambda的参数类型为指针 auto sum_plus_one = [](const uint64_t x, const std::vector<uint64_t>* M) { return (*M)[x] + 1; // 解引用指针后访问vector元素 };
剩下的代码不需要改动,enqueue传&M的逻辑保持不变,这样参数类型就完全匹配了。
方案2:调整enqueue的传参方式,传递引用
如果你想保持lambda的引用参数不变,那需要用std::cref来包装M——因为enqueue通常会对参数做完美转发,直接传M会触发vector的拷贝(这不是我们想要的),用std::cref可以把它包装成常量引用传递:
// 先确保包含functional头文件,std::cref需要它 #include <functional> // lambda保持原来的引用参数不变 auto sum_plus_one = [](const uint64_t x, const std::vector<uint64_t> &M) { return M[x]+1; }; // enqueue时用std::cref包装M,传递常量引用 futures.emplace_back(TP.enqueue(sum_plus_one, x, std::cref(M)));
额外小提醒
看你问题描述里说要给vector的所有元素加1,但当前代码只是计算并返回M[x]+1的值,并没有修改原vector的元素。如果你的实际需求是修改原vector,那可以把lambda改成无返回值的形式,直接修改元素:
auto sum_plus_one = [](const uint64_t x, std::vector<uint64_t>* M) { (*M)[x] += 1; // 直接修改原vector的元素 };
对应的futures类型要改成std::vector<std::future<void>>,后续只需要等待任务完成即可,不需要调用get()获取返回值。
修正后的完整代码示例(方案1)
#include <iostream> #include <vector> #include <thread> #include <hpc_helpers.hpp> #include <threadPool.hpp> int main(int argc, char *argv[]) { // 定义包含5个工作线程的线程池 ThreadPool TP(5); // 调整lambda参数为指针类型 auto sum_plus_one = [](const uint64_t x, const std::vector<uint64_t>* M) { return (*M)[x] + 1; }; uint64_t N = 10; // 向量维度 // 分配向量空间 std::vector<uint64_t> M(N); std::vector<std::future<uint64_t>> futures; // 初始化vector的lambda auto init=[&]() { for(uint64_t i = 0; i< N; ++i) { M[i] = 1; } }; init(); // 线性入队所有任务 for (uint64_t x = 0; x < N; ++x) { futures.emplace_back(TP.enqueue(sum_plus_one, x, &M)); } // 等待并打印所有结果 for (auto& future : futures) std::cout << future.get() << std::endl; return 0; }
备注:内容来源于stack exchange,提问作者DYLAN NICO AMBROSI
相关产品推荐
相关产品推荐

