std::string::find 找不到时返回 std::string::npos;它是 size_type 类型的静态常量,值为 -1 的无符号表示,直接与 -1 比较会引发隐式转换问题,应始终用 if (pos == std::string::npos) 判断。

std::string::find 找不到时返回什么?别直接用 -1 判断
它返回 std::string::npos,不是 -1。虽然 npos 通常定义为 static constexpr size_type npos = -1,但它是无符号类型(size_type),直接写 if (pos == -1) 会触发隐式转换警告甚至逻辑错误——比如在某些编译器 + 优化级别下,-1 被转成极大正数,比较永远为假。
- 正确写法始终是
if (pos == std::string::npos) -
find系列(find、rfind、find_first_of等)都统一返回npos - 如果要找多个匹配,记得从
pos + 1开始下一次搜索,而不是pos + len(除非你明确跳过整个匹配串)
substr 截取越界不会崩溃,但行为可能不符合直觉
substr 的第二个参数是长度,不是结束位置;而且当起始位置超出字符串长度,或长度超限,它会自动截断,不抛异常——这容易掩盖逻辑错误。
-
s.substr(10, 5)在s.size() == 3时返回空串,不是报错 - 想从某位置截到末尾?直接写
s.substr(pos),别写s.substr(pos, s.size() - pos) - 若
pos > s.size(),结果是std::out_of_range异常(C++11 起),不是静默失败
insert / erase 改动字符串时,迭代器和索引可能立刻失效
所有非 const 成员函数修改 std::string 内容时,已存在的迭代器、指针、引用都可能失效——尤其是内部缓冲区重分配后。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 避免在循环里边
erase边用原索引递增:for (int i = 0; i 这会导致跳过下一个字符 - 安全做法是反向遍历,或用返回值更新索引:
i = s.erase(i, len) - s.begin(); -
insert同样:插入后原来指向某位置的const char*指针可能悬空
用 += 和 + 拼接字符串,性能差很多
+= 复用内部缓冲,平均 O(1);+ 每次都新建对象,O(n) 拷贝,尤其在循环中叠加时性能雪崩。
- 错:
result = result + s1 + s2 + s3;→ 生成 3 个临时对象 - 对:
result += s1; result += s2; result += s3; - C++11 起支持移动语义,但
str + std::move(other)并不比+=更优,别为了“看起来高效”硬套
字符串操作本身不复杂,但 npos 的类型陷阱、substr 的静默截断、迭代器失效时机、还有拼接时临时对象的开销——这些点不写进日志也难复现,一出问题就卡半天。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!









