C++ vector能存引用吗 C++ reference_wrapper包装器解决方法【高阶】

7次阅读

vector不能直接存储引用类型,因引用无默认构造、拷贝赋值且不可重绑定;应使用std::reference_wrapper,需#include,通过std::ref/cref创建,取值用.get()或隐式转换

C++ vector能存引用吗 C++ reference_wrapper包装器解决方法【高阶】

vector 不能直接存储引用类型

编译器会直接报错:Error: field of type 'int&' is not assignable。因为引用不是对象,没有默认构造函数、拷贝赋值操作符,也不可重新绑定——而 std::vector 内部依赖这些特性做内存重分配、元素移动和扩容。哪怕写成 std::vector,连模板实例化这关都过不去。

std::reference_wrapper 替代引用

它是个轻量级包装器,本质是可拷贝、可赋值的“引用代理”,底层仍指向原对象,不复制数据。常用场景包括:往容器里存函数参数绑定后的引用、回调列表中保存外部变量别名、避免指针空解引用风险。

关键点:

  • 头文件是 ,不是
  • 创建方式:用 std::ref(x)std::cref(x)(后者生成 const 引用包装)
  • 取值时需显式调用 .get(),或依赖隐式转换(如传给接受 int& 的函数)
  • 不能用 std::reference_wrapper 存储临时对象的引用(生命周期不匹配)

示例:

立即学习C++免费学习笔记(深入)”;

int a = 10, b = 20; std::vector> refs = {std::ref(a), std::ref(b)}; refs[0].get() = 99; // 修改 a 的值 assert(a == 99);

为什么不用 raw 指针或智能指针?

指针需要手动检查是否为空,且语义上表达的是“可选间接访问”;std::shared_ptr 带引用计数开销,std::unique_ptr 不支持共享;而 std::reference_wrapper 明确传达“这个容器里每个元素都必须有效绑定到一个已存在对象”的契约。

但要注意:

  • 它不延长所引用对象的生命周期 —— 若原对象提前析构,get() 调用就是未定义行为
  • 不能放入 std::vector 后再把原变量移出作用域(比如函数返回后局部变量销毁)
  • 调试时 ide 可能不自动展开 std::reference_wrapper,需手动调用 .get()

替代方案对比:什么时候该换别的做法?

如果出现以下情况,std::reference_wrapper 就不是最优解:

  • 需要动态增删绑定目标(它只绑定一次,不可重绑)→ 改用 std::shared_ptr 或索引映射
  • 要跨线程共享且涉及修改 → 需额外加锁,此时裸引用包装反而掩盖同步需求
  • 容器生命周期远长于被引用对象 → 必须改用拥有语义(如 std::vector<:shared_ptr>>)或重构生命周期
  • 只是想避免拷贝大对象 → 优先考虑移动语义或 std::spanc++20),而非绕一圈包引用

真正容易被忽略的是:包装器本身不解决悬垂引用问题,它只是让语法合法了——责任仍在程序员手上确保所引用的对象活得比 vector 久。

text=ZqhQzanResources