为何线程函数参数需用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
相关产品推荐
相关产品推荐

