C++20 —— Ranges
从一个例子说起
1 |
|
Ranges的优势
从上一个例子可以看出,Ranges使得一些操作更简单
- 去除后三个元素进行排序
std::ranges::sort(std::views::drop(v, 3))
- 去除后三个元素进行排序
可以减少一些手误的低级错误
一些corner case更完善,写代码就没必要写一堆特判,这即带来了安全性也方便了使用者
如我们希望从1 - 10倒着输出10个偶数,会发现结果只有四个,即8,6,4,2。
代码:
1
2
3
4for(int num: std::ranges::iota_view(1, 10) | std::views::reverse | std::views::filter(even) | std::views::take(10))
{
std::cout << num << " ";
}
一些概念
Ranges
is a concept, has begin(t) and end(t)
1
2
3
4
5template<class T>
concept range = requires(T& t){
ranges::begin(t);
ranges::end(t);
}array/set/list/vector/… STL容器 和 C数组 都是Ranges
Views
A view is a range
Created via Range Factories or Range Adaptors
懒惰求值,这意味着在没用到之前不会计算,且计算是最小化,不会多计算。
不拥有数据,但不是只读的!
1
2
3
4
5std::vector vec{1, 2, 3, 4, 5, 6};
auto v = std::views::reverse(vec);
std::cout << *(v.begin() + 1) << "\n";//5
*v.begin() = 0;
for(int x: vec) std::cout << x << " ";// {1, 2, 3, 4, 5, 0}
Range Factories
- Range Factories create Views
empty_view<int>e; static_assert(0 == e.size())
std::ranges::single_view
: Create a view with a single elementsingle_view sv1 = 3.1415
std::string s = "hello world";
single_view sv2 = std::move(s)
std::ranges::iota_view
Range Adaptors
- 接受一个range,返回一个view
- 主要配合管道操作符使用,摘自cppreference ”The ranges library includes range algorithms, which are applied to ranges eagerly, and range adaptors, which are applied to views lazily. Adaptors can be composed into pipelines, so that their actions take place as the view is iterated.“ 这告诉了我们管道操作符目前只能对返回view的Range Adaptors使用。
Range Algorithms
一些存在的问题
- 首先是ranges的相关内容命名很长,但可以通过using别名来解决
- 用了using也会有一些命名空间上和std有冲突的命名,比如reverse
具体如下:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!