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 的指针。当它被传递给线程函数时,它会"解包"回原始的引用。

相关推荐
Ashley_Amanda17 小时前
Python 进阶:从熟练到精通的核心技能体系
开发语言·python
你怎么知道我是队长17 小时前
C语言---命令行参数
c语言·开发语言
秋刀鱼程序编程17 小时前
Java编程基础入门(四)---选择循环语句
java·开发语言·算法
优雅的潮叭17 小时前
c++ 学习笔记之 volatile与atomic
c++·笔记·学习
一条咸鱼_SaltyFish17 小时前
WebFlux vs MVC:Gateway集成若依框架的技术选型之争
java·开发语言·微服务·gateway·mvc·开源软件·webflux
独自归家的兔18 小时前
Java反射之根:Class类生成机制深度剖析与最佳实践
java·开发语言
请叫我聪明鸭18 小时前
基于 marked.js 的扩展机制,创建一个自定义的块级容器扩展,让内容渲染为<div>标签而非默认的<p>标签
开发语言·前端·javascript·vue.js·ecmascript·marked·marked.js插件
仍然.18 小时前
Java---反射、枚举、lambda表达式 和 泛型进阶
java·开发语言
Zsy_05100318 小时前
【C++】类和对象(二)
开发语言·c++
Duang007_18 小时前
【万字学习总结】API设计与接口开发实战指南
开发语言·javascript·人工智能·python·学习