应将参数改为 const std::string&;因为函数期望可修改的左值引用,但传入的是字面量等右值,而const引用既能避免拷贝又可安全绑定临时对象。

为什么 std::string 传参报这个错?
这是 C++ 最典型的引用绑定错误,本质是函数期望一个可修改的左值引用(T&),但你传进去的是临时对象(右值),比如字面量、函数返回值、类型转换结果。编译器拒绝绑定,因为修改临时对象没意义,还容易引发未定义行为。
常见触发场景:
- 函数参数是
std::string&,却传了"hello"或func().c_str() - 重载了
void foo(std::string& s),但调用时写foo("abc") - 用
std::move后又试图以非 const 引用接收(比如void bar(std::string& x)接bar(std::move(s)))——这也不行,std::move(s)是右值,仍不能绑定到std::string&
最稳妥的修法:改用 const std::string&
90% 的情况,你根本不需要在函数里修改传入的字符串。把参数改成常量左值引用,既避免拷贝,又能接收字面量、临时对象、变量等各种来源:
void process(const std::string& s) { /* 读取 s 即可 */ }
// ✅ OK
process("hello");
process(std::string("world"));
std::string x = "test";
process(x);
注意:const std::string& 能延长临时对象生命周期,安全可靠;而 std::string&&(右值引用)只适合移动语义场景,别为了“看起来高级”乱用。
真要修改原字符串?那就传左值变量,别传字面量
如果函数逻辑确实需要修改入参(比如解析填充、就地 trim),那它本就不该接受字面量——字面量根本没法改。这时必须确保传的是命名变量:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- ❌ 错误:
trim(" hello ");—— 字面量是右值,且不可修改 - ✅ 正确:
std::string s = " hello "; trim(s);——s是左值,能绑定到std::string&
如果函数接口已定死为 std::string&,又想传字面量,唯一办法是显式构造临时对象并取引用(不推荐):std::string tmp = "abc"; func(tmp);。但这掩盖了设计问题——该函数其实不该承诺“修改输入”,应优先考虑 const 引用 + 返回新值。
警惕隐式转换带来的右值陷阱
比如你写了 void f(std::string& s),又传了个 char*:f("hello")。这里 "hello" 会隐式构造一个临时 std::string,这个临时对象是右值,无法绑定到 std::string&。
解决方式只有两个:
- 把参数改为
const std::string&(推荐) - 或改为接受
const char*/std::string_view(C++17 起更轻量):void f(std::string_view s),它天然支持字面量、std::string、C 风格字符串,且零拷贝
别写 void f(std::string&& s) 来“修复”这个问题——它只接受右值,反而让已有的变量调用失败,属于倒果为因。
核心就一条:看到这个错,先问自己“这个函数真的需要修改传进来的字符串吗?”——十有八九不需要,直接加 const 就完事。硬要绕开它去强转、加 move、甚至用 const_cast,都是在给后续维护埋雷。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










