std::reverse必须传入一对双向迭代器而非容器本身,正确用法为std::reverse(container.begin(), container.end()),返回void且就地修改原序列。

reverse 函数必须传入迭代器,不能直接传容器
很多人写 reverse(vec) 或 reverse(arr) 直接报错,因为 std::reverse 不接受容器对象,只接受一对双向迭代器(begin 和 end)。它本质上操作的是「一段内存区间」,和容器类型无关。
正确用法是:
std::vector<int> v = {1, 2, 3, 4};
std::reverse(v.begin(), v.end()); // ✅</int>
常见错误现象:error: no matching function for call to 'reverse',往往就是漏了 .begin() 和 .end()。
-
std::array、std::deque、std::list同样适用,只要支持双向迭代器 - C 风格数组需手动传指针:
int a[5] = {1,2,3,4,5}; std::reverse(a, a + 5); - 字符串也行:
std::string s = "hello"; std::reverse(s.begin(), s.end());
reverse 是就地反转,不返回新容器
std::reverse 没有返回值(返回类型是 void),它直接修改原序列。如果你需要保留原数据,得先拷贝:
std::vector<int> v = {1, 2, 3};
auto v_rev = v; // 先拷贝
std::reverse(v_rev.begin(), v_rev.end()); // 再反转副本</int>
容易踩的坑:
- 误以为
v = std::reverse(...)能赋值 —— 编译不过 - 在函数里对参数调用
reverse,却没意识到原容器已被改写(尤其是传引用时) - 对
const容器或子范围(如v.begin()+1, v.end()-1)调用时,确保该范围可写
reverse_iterator 不等于 reverse 函数
别把 std::reverse_iterator 和 std::reverse 搞混。前者只是「反向遍历的迭代器类型」,不改变容器内容;后者才是真反转数据。
比如:
std::vector<int> v = {1,2,3};
for (auto it = v.rbegin(); it != v.rend(); ++it) {
std::cout <p>而 <code>std::reverse(v.begin(), v.end())</code> 执行后,<code>v</code> 真变成 <code>{3,2,1}</code>。</p>
<ul>
<li>
<code>rbegin()/rend()</code> 开销极小,适合只读遍历</li>
<li>要永久翻转顺序,必须用 <code>std::reverse</code> 或手动 swap</li>
<li>某些算法(如 <code>std::sort</code>)配合 <code>greater<int>()</int></code> 可模拟“逻辑上倒序”,但物理顺序不变</li>
</ul>
<h3>性能与边界:reverse 时间复杂度是 O(n),但要注意迭代器有效性</h3>
<p><code>std::reverse</code> 内部是首尾交换,时间复杂度 O(n/2),空间 O(1),很高效。但有两个易忽略点:</p>
<ul>
<li>传入的两个迭代器必须属于同一容器,且 <code>first</code> 可达 <code>last</code>(即 <code>[first, last)</code> 是合法范围),否则行为未定义</li>
<li>如果容器在反转过程中被其他线程修改,结果不可预测 —— 它不是线程安全的</li>
<li>对空容器或单元素容器调用是安全的:<code>reverse(v.begin(), v.begin())</code> 或 <code>reverse(v.begin(), v.begin()+1)</code> 都没问题</li>
</ul>
<p>最常被忽略的是:反转 <code>std::list</code> 时虽然语法一样,但底层是节点指针重连,不是逐个 swap 元素 —— 这不影响使用,但知道这点能避免误判性能。</p></int>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











