std::rotate 是循环左移操作,将 [first, middle) 移至 [middle, last) 之后;其底层常通过三次反转实现:先反 [first, middle),再反 [middle, last),最后反 [first, last)。

直接说结论:std::rotate 不是“旋转容器”,而是把一个区间按指定位置做**循环左移**——它把 [first, middle) 搬到 [middle, last) 后面,等价于以 middle 为分界点做一次左循环移位。
为什么 std::rotate 看起来像“反转三次”?
标准库实现通常基于三步反转(Knuth 提出),因为这样只需 O(n) 时间 + O(1) 额外空间,且稳定(保持相等元素相对顺序):
- 先反转
[first, middle) - 再反转
[middle, last) - 最后反转整个
[first, last)
这不是用户要写的逻辑,但理解它能帮你避开误区:比如误以为 std::rotate 是“顺时针转圈”,其实它没有方向参数,只有“以哪个迭代器为新起点”的语义。
std::rotate 的典型用法和易错点
常见错误是传错 middle 迭代器——它必须在 [first, last) 范围内,且不能等于 last(否则未定义行为)。正确用法如下:
立即学习“C++免费学习笔记(深入)”;
- 想把前 k 个元素移到末尾?
middle = begin + k,前提是k - 想把后 k 个元素移到开头?等价于
middle = end - k - 对
std::vector、std::deque、std::array直接用没问题;但对std::list,虽然可用,性能是O(n)(需遍历找middle),不如splice - 对
std::forward_list不支持 —— 它没有双向迭代器,std::rotate要求至少是ForwardIterator,而它只提供ForwardIterator,但标准库未为它特化,实际编译会失败
std::vectorv = {1, 2, 3, 4, 5}; std::rotate(v.begin(), v.begin() + 2, v.end()); // middle 指向 3 // v 变成 {3, 4, 5, 1, 2}
替代方案:什么时候不该用 std::rotate?
如果只是临时取“旋转后某位置的值”,别真调用 std::rotate —— 它修改原容器。此时用模运算索引更轻量:
- 原容器
v,想访问“左旋 k 位后下标 i 的值”:用v[(i + k) % v.size()] - 需要多次不同旋转视图?考虑封装成
rotated_view(C++20std::views::drop+std::views::take组合) - 大量频繁旋转且不允许修改原数据?用
std::deque配合push_back/pop_front模拟队列式移位,比反复rotate更快
最常被忽略的一点:std::rotate 对空区间(first == last)合法,但若 middle 不在 [first, last) 内,行为未定义——调试时崩溃可能不报具体原因,只显示迭代器失效或越界断言失败。











