应优先使用const t&作为大对象形参类型,以避免拷贝且禁止修改实参;它可绑定左值和右值,但不可用于长期持有临时对象,对小对象应优先传值。

形参写成 const T& 就行,别加 std::move 或 const T&&
大对象(比如 std::vector、std::string、自定义类)用常量引用传参,核心就是让形参类型是 const T&。这能避免拷贝,又禁止函数内修改实参——安全且高效。
常见错误是误以为“加 std::move 能更快”,或者混用 const T&&,结果要么编译失败,要么意外触发移动语义(破坏原对象)。
- ✅ 正确写法:
void process(const std::vector<int>& data)</int> - ❌ 错误写法:
void process(const std::vector<int>&& data)</int>(这是右值引用,不能绑定左值) - ❌ 危险写法:
void process(std::vector<int>&& data)</int>(可能偷走调用方的资源) - ❌ 多余写法:
void process(const std::vector<int>& data) { ... std::move(data); }</int>(data是 const 的,std::move后仍是 const 左值,毫无意义)
什么时候必须用 const T&?看调用方是不是左值
如果调用时传的是变量名、命名对象、或返回左值的函数(比如 get_data() 返回 std::vector<int>&</int>),那只能绑定到 const T&,不能绑定到 T&& 或非 const 引用。
例如:
std::vector<int> v = {1,2,3};
process(v); // v 是左值 → 只匹配 const T&</int>
若你把形参写成 std::vector<int>&</int>(无 const),就会编译报错:cannot bind non-const lvalue reference to an rvalue(实际是左值,但错误信息常混淆);若写成 std::vector<int>&&</int>,同样不匹配。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
const T& 也能绑定右值,但别依赖它来“延长生命周期”
临时对象(如 std::vector{1,2,3})是右值,const T& 确实能绑定,并自动延长其生命周期到引用作用域结束——但这只是语言特性,不是设计意图。
实际工程中应避免依赖这点,尤其当函数可能异步保存该引用,或传递给其他作用域更长的上下文时,容易悬垂。
- 安全用法:临时对象只在函数体内读取,不存储、不转发
- 危险用法:
cache_ref = std::vector{1,2,3};(cache_ref是const std::vector<int>&</int>成员)→ 析构即悬垂 - 替代方案:需要长期持有,就用值语义(
T)或智能指针(std::shared_ptr<t></t>)
性能没差别?别忽略编译器优化边界
虽然 const T& 避免了拷贝,但编译器未必总能完全消除间接访问开销(比如无法内联、缓存局部性差)。对极小对象(如 int、std::pair<int></int>),按值传递反而更高效。
判断标准不是“大不大”,而是“是否满足 std::is_trivially_copyable_v<t></t> 且尺寸 ≤ 寄存器宽度(通常 ≤ 16 字节)”。
- 推荐按值传:
int、double、std::array<char></char> - 推荐按
const T&传:std::string、std::vector、任何含动态内存或复杂构造的类 - 不确定时,用
sizeof(T)查大小,再结合 ABI 约定(x86-64 下通常 ≤ 16 字节适合按值)
真正容易被忽略的,是把 const T& 当万能解药——它解决不了所有权转移、线程安全、或跨 DLL 边界的内存布局兼容问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










