Ranges是C++20引入的一个库。其标准可以参考Ranges library。因为还很新,不是所有额编译器都提供,但是有开源的实现range-v3可以参考使用。
A beginner’s guide to C++ Ranges and Views这篇文章是很好的入门。如果你熟悉C++的各种形式的iterator的话,对于ranges也不会太陌生,它们都对序列进行操作。和Iterators不同的是,Ranges采用了C++ 20的最新特性Concepts,并且是惰性执行的。
下面是常见的range类型:
- std::ranges::input_range,只可单次遍历的单向range
- 比如 std::forward_list, std::list, std::deque, std::array
- std::ranges::forward_range,可以多次遍历的单向range
- 比如 std::forward_list, std::list, std::deque, std::array
- std::ranges::bidirectional_range,双向range
- 比如 std::list, std::deque, std::array
- std::ranges::random_access_range,支持随机访问的range
- 比如 std::deque, std::array
- std::ranges::contiguous_range,内容上连续的range
- std::array
此外还有size_range,output_range等等。
range的操作目标是各种container,但是操作的手段却是通过view这个类型来表达的。比如:
std::vector vec{1, 2, 3, 4, 5, 6};
auto v = std::views::reverse(vec);
多个view返回的结果可以串在一起:
std::vector vec{1, 2, 3, 4, 5, 6};
auto v = vec | std::views::reverse | std::views::drop(2);
前面提到ranges是惰性求值的。所以即便指定了view,只有真正获取元素的时候,view才会被执行。
C++20: The Ranges Library一文中列举了不同的view:
std::all_view, std::views::all // takes all elements
std::ref_view // takes all elements of another view
std::filter_view, std::views::filter // takes the elements which satisfies the predicate
std::transform_view, std::views::transform // transforms each element
std::take_view, std::views::take // takes the first N elements of another view
std::take_while_view, std::views::take_while // takes the elements of another view as long as the predicate returns true
std::drop_view, std::views::drop // skips the first N elements of another view
std::drop_while_view, std::views::drop_while // skips the initial elements of another view until the predicate returns false
std::join_view, std::views::join // joins a view of ranges
std::split_view, std::views::split // splits a view by using a delimiter
std::common_view, std::views::common // converts a view into a std::common_range
std::reverse_view, std::views::reverse // iterates in reverse order
std::basic_istream_view, std::istream_view // applies operator>> on the view
std::elements_view, std::views::elements // creates a view on the N-th element of tuples
std::keys_view, std::views::keys // creates a view on the first element of a pair-like values
std::values_view, std::views::values // creates a view on the second elements of a pair-like values
C++ code samples before and after Ranges给出了一些代码上的示例。
VS 2019 16.8引入了不少ranges的特性。