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

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::span(c++20),而非绕一圈包引用
真正容易被忽略的是:包装器本身不解决悬垂引用问题,它只是让语法合法了——责任仍在程序员手上确保所引用的对象活得比 vector 久。