C++使用std::thread调用其他类带参函数报错求助
刚接触C++,若问题较为浅显还请见谅。我尝试创建std::thread来运行另一个类的带参成员函数,但运行代码时出现报错。代码结构如下:
int main(){ Engine engine; Sounds sounds; std::thread t(&Sounds::ManageSounds, &sounds, &engine); /*some stuff*/ t.join(); } class Sounds{ void ManageSounds(Engine en){ /*some stuff*/ } }
运行上述代码时触发错误:
error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues 129 |
typename decay<_Args>::type...>::value
若将ManageSounds()改为无参函数,并移除线程创建时的&engine参数,代码可完全正常运行,求该问题的解决方法。
解决方法
问题原因
你传递给线程的是Engine*类型的指针(&engine),但ManageSounds函数的参数是Engine值类型。std::thread在处理参数时会执行decay转换,无法自动把Engine*隐式转换成Engine对象,导致参数类型不匹配,触发断言错误。
具体修正方案
方案1:修改函数参数为指针(最直接)
把ManageSounds的参数改成Engine*,和你传递的&engine类型匹配:class Sounds{ void ManageSounds(Engine* en){ /*some stuff*/ } };方案2:传递对象值(会产生拷贝)
如果一定要保留值类型参数,创建线程时直接传engine而非&engine,但这样会拷贝一份Engine对象:std::thread t(&Sounds::ManageSounds, &sounds, engine);方案3:传递引用避免拷贝(需保证对象生命周期)
先把ManageSounds的参数改成引用类型,再用std::ref包裹实参传递(注意要确保engine的生命周期长于线程,这里main里的engine直到t.join()后才销毁,是安全的):class Sounds{ void ManageSounds(Engine& en){ /*some stuff*/ } }; // 创建线程时使用std::ref std::thread t(&Sounds::ManageSounds, &sounds, std::ref(engine));
内容的提问来源于stack exchange,提问作者MyselfAndOnlyMe

