std::ranges::views::reverse, std::ranges::reverse_view
std::ranges::views::reverse, std::ranges::reverse_view
C++20 中用于反转范围元素的工具
核心概念
- 功能:将输入范围的元素按逆序呈现。
- 适用场景:需要逆序遍历或处理范围时(如反向搜索、逆序输出)。
- 惰性求值:不会实际修改底层数据,仅在访问时动态反转顺序。
std::ranges::reverse_view
- 要求:
- 输入范围必须是双向范围(即支持
ranges::begin
和ranges::end
返回双向迭代器)。
- 输入范围必须是双向范围(即支持
示例 1:基本用法
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vec = {1, 2, 3, 4, 5};
std::ranges::reverse_view reversed_view{vec};
for (int x : reversed_view)
{
std::cout << x << " "; // 输出:5 4 3 2 1
}
}
示例 2:组合其他视图
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto even = vec | std::views::filter([](int x) { return x % 2 == 0; });
auto reversed_even = even | std::views::reverse;
for (int x : reversed_even)
{
std::cout << x << " "; // 输出:4 2
}
}
std::ranges::views::reverse
- 定义:范围适配器对象,可通过管道操作符
|
简化reverse_view
的创建。 - 等效操作:
views::reverse(r)
等价于reverse_view<decltype(r)>{r}
。
示例 3:使用管道操作符
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vec = {1, 2, 3, 4, 5};
auto reversed = vec | std::views::reverse;
for (int x : reversed)
{
std::cout << x << " "; // 输出:5 4 3 2 1
}
}
注意事项
- 双向迭代器要求:输入范围必须提供双向迭代器(如
std::vector
、std::list
支持,但std::forward_list
不支持)。 - 性能:反转操作的时间复杂度为 O(1),实际遍历时通过反向移动迭代器实现。
- 数据所有权:
reverse_view
不拥有底层数据,需确保原始数据的生命周期足够长。
与 std::reverse
的区别
| 特性 | std::ranges::reverse_view
| std::reverse
|
修改数据 | 否(仅视图) 是(直接修改容器)
时间复杂度 | O(1)(惰性求值) O(N)(实际反转元素)
适用场景 | 需要临时逆序访问 需要永久反转数据
示例 4:与 std::reverse
对比
#include <algorithm>
#include <ranges>
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用 reverse_view(不修改原数据)
auto reversed_view = vec | std::views::reverse;
std::cout << "Original: ";
for (int x : vec) std::cout << x << " "; // 输出:1 2 3 4 5
// 使用 std::reverse(修改原数据)
std::reverse(vec.begin(), vec.end());
std::cout << "\nAfter std::reverse: ";
for (int x : vec) std::cout << x << " "; // 输出:5 4 3 2 1
}
总结
reverse_view
:提供逆序访问的视图,不修改底层数据。views::reverse
:通过管道操作符简化reverse_view
的创建。- 适用场景:需要临时逆序操作或与其他视图组合时。