You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用std::thread调用其他类带参函数报错求助

问题:创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:01:00