我正在尝试使用https://github.com/Fdhvdu/ThreadPool作为后端线程池来实现自己的并行版本
我将任务分成多个部分,并使用以下功能启动线程:
template <typename Callable>
void launchRange(int id, Callable func, int k1, int k2)
{
for (int k = k1; k < k2; k++) {
func(k);
}
}
我遇到的问题是如何将此Callable
传递给线程池
相关部分是:
poolPtr->add(launchRange, func, i1, i2);
但是我一直收到编译错误。错误是:
...\ithreadpoolitembase.hpp(36): error C2027: use of undefined type 'std::tuple<conditional<_Test,void(__cdecl *&)(int),_Ty>::type,conditional<_Test,int&,int>::type,conditional<_Test,int&,int>::type>'
with
[
_Ty=void (__cdecl *)(int)
]
add
的界面是
template<class Func,class ... Args>
inline thread_id add(Func &&func,Args &&...args);
我将Visual Studio 2017 Community 15.4与/std:c++17
一起使用
答案 0 :(得分:2)
launchRange
是功能模板,而不是功能。
除非完成重载解析,否则您不能将功能模板作为功能传递。该行不会触发超载解析。
auto launchRange = [](int id, auto&& func, int k1, int k2)
{
for (int k = k1; k < k2; k++) {
func(k);
}
};
以上是一个lambda,其行为与launchRange
模板非常相似,但它是一个实际的对象,而不仅仅是模板。
由于您没有传递add
id
参数,它仍然无法正常工作。
poolPtr->add(launchRange, 77, func, i1, i2);
可能会编译。
我不特别喜欢特定的线程池实现。我的意思是,您可以拥有多少个无意义的pimpl层?多少无意义的堆分配?而且,它默认通过引用传递,这在将内容传递给另一个线程时是一个可怕的想法。
我认为在这里争论是一个坏计划。避免使用它们。
poolPtr->add([=]{ launchRange(77, func, i1, i2); });
这也消除了创建auto launchRange = []
lambda的需要。错误最终变得更容易阅读。