ref关键字

std::ref 是什么?

简单的一句话: std::ref 是一个包装器 ,用来告诉 std::thread(以及其他标准库函数如 std::bind):"请传递这个变量的引用(地址) ,而不是它的拷贝(副本)"。

为什么需要它?

std::thread 的构造函数在设计上非常谨慎。为了防止线程运行在分离模式(detach)下访问已经销毁的局部变量,它默认会把所有参数拷贝一份存到线程独立的存储空间里。

这就导致了一个问题:即使你在函数参数里写了 void func(int& n)

std::thread 依然会先拷贝一个副本,然后把这个副本的引用传给函数。

  • 没有 std::ref:你修改的是副本,主线程里的原始变量不会变
  • std::ref:你修改的是原始变量。
代码对比
复制代码
#include <iostream>
#include <thread>
#include <functional> // std::ref 实际上在这里,但 <thread> 通常包含了它

void worker(int& n) {
    n += 10;
}

int main() {
    int n = 0;

    // --- 错误示范 ---
    // std::thread t1(worker, n); 
    // 编译可能会报错,或者虽然编译通过,但 n 仍然是 0。
    // 因为 thread 内部机制拷贝了 n,试图把临时拷贝传给非 const 引用是非法的/无效的。

    // --- 正确示范 ---
    std::thread t2(worker, std::ref(n)); 
    t2.join();

    std::cout << "n is now: " << n << std::endl; // 输出 10
    return 0;
}

底层原理: std::ref(n) 返回一个 std::reference_wrapper<int> 对象。这个对象是可以拷贝的,但它内部保存的是 n 的指针。当它被传递给线程函数时,它会"解包"回原始的引用。

相关推荐
FQNmxDG4S7 小时前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
前端老石人8 小时前
HTML 字符引用完全指南
开发语言·前端·html
matlab_xiaowang8 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
虹科网络安全8 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
axng pmje8 小时前
Java语法进阶
java·开发语言·jvm
汉克老师8 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
老前端的功夫9 小时前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python
qq_435287929 小时前
第9章 夸父逐日与后羿射日:死循环与进程终止?十个太阳同时值班的并行冲突
java·开发语言·git·死循环·进程终止·并行冲突·夸父逐日
止语Lab9 小时前
从手动到框架:Go DI 演进的三个拐点
开发语言·后端·golang
yaoxin5211239 小时前
397. Java 文件操作基础 - 创建常规文件与临时文件
java·开发语言·python