std::reverse是就地反转算法,返回void,必须传入有效迭代器范围且不越界,对std::string等连续容器有效,但不可用于std::string_view或const char*。

std::reverse 会直接修改原字符串,不是返回新字符串
很多人以为 std::reverse 像 Python 的 reversed() 那样返回一个迭代器或新对象,其实它是个就地(in-place)算法:只改传入的区间,不分配新内存,也不返回字符串。如果你写了 auto s2 = std::reverse(s.begin(), s.end());,编译都过不去——它返回的是 void。
正确写法就是直接调用,别想着“赋值”:
std::string s = "hello"; std::reverse(s.begin(), s.end()); // ✅ 修改 s 本身 // 此时 s 是 "olleh"
- 必须传两个迭代器:起始和末尾(注意是
end(),不是end()-1) - 对
std::string、std::vector等连续容器有效;对std::list要用它的成员函数list::reverse() - 如果传了空字符串或单字符,不会出错,但也没实际效果
反转子串要用对迭代器范围,别越界
想反转从下标 2 开始的 3 个字符?容易写成 std::reverse(s.begin()+2, s.begin()+3),结果只翻了 1 个字符——因为第二个参数是“过去-end”,不是“长度”。
正确计算方式是:begin + 起始索引 到 begin + 起始索引 + 长度:
立即学习“C++免费学习笔记(深入)”;
std::string s = "abcdef"; std::reverse(s.begin() + 2, s.begin() + 2 + 3); // 反转 "cde" → s 变成 "abedcf"
- 务必检查边界:若
2 + 3 > s.size(),行为未定义(通常崩溃或乱翻) - 建议加保护:用
std::min(s.begin() + pos + len, s.end())截断 -
std::string_view不能直接传给std::reverse,它不拥有数据,得先转成可修改容器
char 数组用 reverse 得小心指针类型
C 风格字符串(char[] 或 char*)不能直接丢给 std::reverse,因为没有 begin()/end() 成员。你得手动算长度,并确保以 \0 结尾,否则可能翻到内存垃圾。
安全做法是用 std::strlen 获取有效长度,再构造迭代器范围:
char buf[] = "world"; size_t len = std::strlen(buf); std::reverse(buf, buf + len); // ✅ buf 现在是 "dlrow"
- 千万别写
std::reverse(buf, buf + sizeof(buf))——这会把末尾的\0和 padding 都翻进去,破坏字符串结构 - 如果指针是
const char*,std::reverse编译失败:它要求可写迭代器 - 对栈上数组可用
std::size(buf),但对堆分配或函数参数传进来的char*必须靠strlen或额外传长度
性能上没坑,但别在 hot path 里反复构造临时 string
std::reverse 时间复杂度是 O(n/2),内部就是交换首尾元素,非常快。真正拖慢的往往是误用场景:比如每次循环都 new 一个 std::string,翻完又扔掉。
- 如果只是临时需要反转视图(比如比较回文),考虑用反向迭代器:
std::string::rbegin()/std::string::rend(),避免修改原数据 - 频繁反转同一字符串?检查逻辑——也许该换存储顺序,或用双端队列
- 跨线程使用时注意:
std::reverse不做同步,原字符串得自己保证无竞争访问
最常被忽略的一点:反转操作本身很轻,但如果你在反转前忘了确认字符串是否为空、是否含嵌入 \0、或者混用了 signed/unsigned char 指针,问题就出在边界,不在 std::reverse 本身。










