我是线程新手,我试图将重载方法传递给std :: thread,如下例所示
#include <iostream>
#include <thread>
int do_calculation(int x)
{
std::cout<<x;
}
float do_calculation(float x)
{
std::cout<<x;
}
int main()
{
std::thread t1(do_calculation,20);
std::thread t2(do_calculation,200.0f);
return 0;
}
但该程序没有编译并抛出错误
no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, int)'
std::thread t1(do_calculation,20);
有没有办法在线程中调用重载方法?
答案 0 :(得分:8)
您需要转换函数来解决重载问题:
std::thread t1(static_cast<int(*)(int)>(do_calculation),20);
std::thread t2(static_cast<float(*)(float)>(do_calculation),200.0f);
此外,您需要join
或detach
您的帖子,以免您冒险前往std::terminate
:
t1.join();
t2.join();
答案 1 :(得分:7)
或者,您可以将调用包装在lambda中
std::thread t1([](int e) {do_calculation(e);}, 20);
std::thread t2([]() { do_calculation(200.0f); });
答案 2 :(得分:3)
如果您可以使用C ++ 14,那么作为转换的替代方法,您可以将函数调用包装在lambda中,即自动参数类型推导。这将允许重载解析和类型扣除为您工作
std::thread t1([](auto var){ do_calculation(var); },20);
std::thread t2([](auto var){ do_calculation(var); },200.0f);
答案 3 :(得分:1)
#define RETURNS( ... ) \
noexcept(noexcept( __VA_ARGS__ )) \
-> decltype( __VA_ARGS__ ) \
{ return __VA_ARGS__; }
#define OVERLOAD_SET( ... ) \
struct { \
template<class...Ts> \
auto operator()(Ts&&...ts)const\
RETURNS( __VA_ARGS__( std::forward<Ts>(ts)... ) )\
}
现在我们可以做到:
static OVERLOAD_SET( do_calculation ) do_calculation_v;
和do_calculation_v
是一个对象,表示do_calculation
的重载集。
int main() {
std::thread t1(do_calculation_v,20);
std::thread t2(do_calculation_v,200.0f);
return 0;
}
在c++14中,我们可以使用lambdas执行此操作,而不需要命名对象:
#define OVERLOAD_SET( ... ) \
[](auto&&...args) RETURNS( __VA_ARGS__( decltype(args)(args)... ) )
int main() {
std::thread t1(OVERLOAD_SET(do_calculation),20);
std::thread t2(OVERLOAD_SET(do_calculation),200.0f);
}
有一个c++20提案可以让你在没有宏的情况下更简单一点:
int main() {
std::thread t1([](auto...args)=>do_calculation(decltype(args)(args)...),20);
std::thread t2([](auto...args)=>do_calculation(decltype(args)(args)...),200.0f);
}
备份到c++11,如果我们不关心noexcept
或返回值等,我们可以这样做:
int main() {
std::thread t1([]{do_calculation(20);});
std::thread t1([]{do_calculation(200.f);});
}
涉及90%涉及的案件。如果您的值不是硬编码的并且复制起来很便宜,那么只需在[]
lambda捕获列表中捕获它们。