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

为何线程函数参数需用const引用?非const引用报错原因解析

非const左值引用与const左值引用在std::thread参数中的差异

当在Modify_X函数中使用int &x作为参数时,程序触发如下错误;但改用const int &x时程序可正常运行,两者的核心差异如下:

代码示例

#include <iostream>
#include <thread>
using namespace std;

class Test
{
    int x;
    public:
    Test():x(110){}
    void Modify_X(int & x)
    {
       cout<<"address of x = "<<&x<<endl;
       x = x+10;
       cout<<"after modify x = "<<x<<endl;
    }
};

int main()
{
    Test t1;
    int y = 30;
    thread t_obj(Test::Modify_X, t1, y); // 注:原代码末尾多了一个冗余的')',已修正
    t_obj.join();
    cout<<"address of y = "<<&y<<endl;
    cout<<"value of y = "<<y<<endl;
    return 0;
}

错误信息

静态断言失败:std::thread的参数在转换为右值后必须可调用

差异解析

  • 使用int &x时的问题:
    std::thread构造时会将所有传入的参数复制/移动为右值,存储到线程内部的独立存储区。而int &x是非const左值引用,C++规则不允许它绑定到右值(线程存储的y的副本是右值),因此目标函数无法被正常调用,触发静态断言错误。

  • 使用const int &x时的正常逻辑:
    C++标准允许const左值引用绑定到右值,此时引用会绑定到线程内部存储的参数副本上。虽然函数无法修改原始变量y,但可以正常访问副本的值,因此程序能顺利运行。

额外说明:若需修改原始变量

如果你的需求是在线程中修改原始的y,不能直接传y,需要用std::ref()包装参数,让std::thread传递引用而非副本。同时,成员函数的类对象参数如果需要操作原始实例,也要用std::ref()或指针,示例如下:

int main()
{
    Test t1;
    int y = 30;
    thread t_obj(&Test::Modify_X, std::ref(t1), std::ref(y));
    t_obj.join();
    cout<<"address of y = "<<&y<<endl;
    cout<<"value of y = "<<y<<endl;
    return 0;
}

内容的提问来源于stack exchange,提问作者Amruta Dhanawade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:20:11