值参数适合传基础类型和小型无资源管理的结构体;判断标准是sizeof(T)≤24字节且不含动态内存或非平凡构造/析构;需隔离修改时必须值传;小数据值传比const引用更高效且线程安全。

值参数适合传 int、float、char 等基础类型
这些类型通常占 1–8 字节,拷贝开销极小,编译器还可能做寄存器优化,实际不产生内存复制。用 int、double、bool、char 做形参时,默认值传递完全合理,不必强行改成引用。
小型结构体或类也能安全值传递
判断标准不是“是不是 class”,而是对象大小和是否含资源管理逻辑。比如:
-
struct Point { int x, y; };—— 8 字节,值传没问题 -
struct Vec2f { float x, y; };—— 同样轻量 - 但
std::string、std::vector<int>即使空着也含指针成员,值传会触发深拷贝,应避免
经验法则是:sizeof(T) <= 3 * sizeof(void*)(即 ≤24 字节在 64 位系统上)且不含动态内存或非平凡构造/析构函数,才考虑值传。
需要隔离修改或明确不共享状态时必须用值传
比如函数内部要排序、截断、归一化输入,又不希望影响调用方原始数据——这时值传是语义最清晰的选择。常见于数学计算、配置解析、协议字段解包等场景。
立即学习“C++免费学习笔记(深入)”;
- 错误做法:
void process(Config& cfg)内部改了cfg.timeout,调用方意外受影响 - 正确做法:
void process(Config cfg),函数拿到的是干净副本
注意:如果结构体含 const 成员或自定义拷贝控制,还得确认拷贝行为符合预期,否则可能编译失败或逻辑异常。
别把 const 引用当银弹,小数据值传反而更直接
有人看到“避免拷贝”就统一上 const T&,但对 int 这类类型,引用传递反而多一次内存寻址(取地址再解引),生成的指令未必比直接传值高效。而且 const int& 无法绑定到字面量(如 foo(42))除非编译器允许临时量延长生命周期,而值传无此限制。
真正容易被忽略的是:值传提供天然的线程安全边界——副本只在当前栈帧存在,不存在数据竞争风险;而引用或指针若跨线程误用,问题会延迟暴露且难复现。


















