std::reverse仅原地反转容器元素顺序,不改变类型或大小,要求双向迭代器,无返回值,空容器和单元素安全,但不可用于const容器、map/set或unordered_map。

std::reverse 不能直接反转 std::array 或 std::vector 的“类型”
它只反转元素顺序,不改变容器类型或大小。常见误解是以为 std::reverse 能让 std::vector<int></int> 变成“反向视图”或返回新容器——它没有返回值,原地修改,且要求迭代器支持双向遍历。
- 必须传入一对满足 LegacyBidirectionalIterator 要求的迭代器,比如
v.begin()和v.end() - 对
std::list也能用,但效率不如list::reverse()(后者是 O(1) 链表指针翻转) - 不能用于
std::forward_list:它只有单向迭代器,std::reverse编译失败,错误信息类似no match for 'operator++'
反转 vector、string、array 的标准写法
所有支持随机访问或双向遍历的序列容器,都用 std::reverse(first, last),注意 last 是尾后迭代器。
#include <algorithm>
#include <vector>
#include <string>
std::vector<int> v = {1, 2, 3, 4};
std::reverse(v.begin(), v.end()); // v 变成 {4, 3, 2, 1}
std::string s = "hello";
std::reverse(s.begin(), s.end()); // s 变成 "olleh"
std::array<char> a = {'a', 'b', 'c', 'd'};
std::reverse(a.begin(), a.end()); // a 变成 {'d', 'c', 'b', 'a'}
</char></int></string></vector></algorithm>
-
std::array的begin()/end()返回普通指针,完全满足要求 - 如果只反转部分区间,比如前三个元素:
std::reverse(v.begin(), v.begin() + 3) - 对
const容器无效:传入const_iterator会导致编译错误,因为std::reverse内部要解引用并赋值
反转 map/set 等关联容器?别试了
std::map、std::set 的迭代器是只读的(key 不可变),且底层是红黑树,元素按 key 排序存储。调用 std::reverse 会触发编译错误,典型提示是 assignment of read-only location。
- 真要“逆序遍历”,用
rbegin()/rend():它们返回反向迭代器,逻辑上就是从大到小 - 若需把键值对拷贝出来再反转,得先放进
std::vector:std::vector<:pair k>> vec(m.begin(), m.end())</:pair>,再std::reverse(vec.begin(), vec.end()) - 不要试图对
std::unordered_map反转——它本就无序,反转没意义,且其迭代器不保证双向性(C++11/14 中可能只是前向)
性能与边界陷阱:空容器、单元素、自定义类型
std::reverse 时间复杂度是 O(n/2),空间 O(1),但几个边界容易忽略。
- 空容器安全:
v.begin() == v.end(),函数直接返回,没问题 - 单元素也安全:
first和last-1指向同一位置,交换操作不执行 - 自定义类型必须可移动或可复制,且赋值操作符不能抛异常(否则可能导致未定义行为);若类型有非平凡析构,反转过程不会影响生命周期
- 最常踩的坑:传错迭代器范围,比如写成
std::reverse(v.data(), v.data() + v.size())——虽然对vector有效,但v.data()是裸指针,不是标准容器迭代器,在某些调试模式或自定义分配器下可能失效;坚持用begin()/end()
真正要注意的是:它不检查迭代器有效性。传入野指针或已失效迭代器(比如容器被 move 后又用原迭代器),行为未定义,调试时很难定位。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











