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

相关推荐
古城小栈12 小时前
Rust语言:优势解析与擅长领域深度探索
开发语言·后端·rust
superman超哥12 小时前
Rust Cargo.toml 配置文件详解:项目管理的核心枢纽
开发语言·后端·rust·rust cargo.toml·cargo.toml配置文件
玄同76512 小时前
面向对象编程 vs 其他编程范式:LLM 开发该选哪种?
大数据·开发语言·前端·人工智能·python·自然语言处理·知识图谱
froginwe1112 小时前
SQLite Indexed By
开发语言
虾说羊12 小时前
JVM 高频面试题全解析
java·开发语言·jvm
毕设源码-赖学姐13 小时前
【开题答辩全过程】以 基于PHP的国学诗词网站与推荐系统的设计与实现为例,包含答辩的问题和答案
开发语言·php
盼哥PyAI实验室13 小时前
[特殊字符]️ 实战爬虫:Python 抓取【采购公告】接口数据(含踩坑解析)
开发语言·爬虫·python
wjs202413 小时前
PostgreSQL NULL 值处理与优化
开发语言
prettyxian13 小时前
【QT】Qt从零入门指南:创建你的第一个GUI程序
开发语言·qt