为何向std::thread传递引用参数需使用std::ref和std::cref?
std::ref/std::cref 在 std::thread 中的作用解析
核心逻辑:std::thread 的参数传递机制
std::thread 构造时,会拷贝所有传入的实参到线程自身的内部存储中,之后再把这些拷贝后的参数转发给线程函数。这种设计是为了避免原变量提前销毁导致线程访问非法内存,但也带来了引用参数的适配问题。
直接传 X 为什么报错?
你的线程函数 thread_executor 要求的参数是 int &(非const左值引用)。如果直接写 std::thread worker1(thread_executor, X):
- std::thread 会先拷贝X的值,生成一个临时的int对象;
- C++规则明确禁止临时变量绑定到非const左值引用,编译器会直接抛出错误,程序自然无法运行。
std::ref 的作用
std::ref(X) 会返回一个 std::reference_wrapper<int> 类型的包装器对象,它相当于一个可以被隐式转换成原变量引用的"代理"。当std::thread把这个包装器转发给线程函数时:
- 包装器会自动转换成
int &类型,完美匹配thread_executor的参数要求; - 线程函数实际操作的是原变量X,而非拷贝后的临时对象,这就实现了通过引用传递变量给线程的目的。
std::cref 的补充说明
std::cref 是 std::ref 的const版本,它返回的包装器会被隐式转换成 const int &。如果你的线程函数参数是 const int &,用 std::cref(X) 就能在避免拷贝的同时,保证原变量不会被线程函数修改。
内容的提问来源于stack exchange,提问作者PhiloRobotist
相关产品推荐
相关产品推荐

