Reputation: 155
cppreference states:
The ranges library is an extension and generalization of the algorithms and iterator libraries that makes them more powerful by making them composable and less error-prone.
The library creates and manipulates range views, lightweight objects that indirectly represent iterable sequences (ranges).
It mentions using range views, which are, as cppreference states:
The range concept defines the requirements of a type that allows iteration over its elements by providing an iterator and sentinel that denote the elements of the range.
But from an outside perspective, it just seems like a wrapper of an iterator with a concept
. So the main question is:
Upvotes: 10
Views: 2186
Reputation: 63947
The constrained algorithms in namespace std::ranges
are niebloids, which means - among other things - that you can pass the entire algorithm as a function parameter, or otherwise assign it to a variable.
void do_work( auto algorithm, Foo::Type &a, Foo::Type &b )
{
algorithm( a, b );
}
I could pass std::ranges::swap
as the first parameter to this function. a
and b
will get swapped correctly.
But std::swap
? That won't compile! And if you worked to get it to compile, you still won't know if it's doing the right thing.
First, std::swap
is a template and you can't pass a template as a function parameter. Second, std::swap
isn't aware if there might be a better match Foo::swap
function. The niebloid does.
Upvotes: 1
Reputation: 218138
what are the problems with using regular iterators that ranges library solves (code examples will be appreciated)?
It might avoid some mistakes with temporary container:
// assuming std::vector<int> compute_vector();
// Following is wrong begin and end refers to different (temporary) containers
const bool KO = std::is_sorted(compute_vector().begin(),
compute_vector().end()); // WRONG
// Here all is ok.
const bool OK = std::ranges::is_sorted(compute_vector());
Upvotes: 6
Reputation: 185
The second one will allow you to pipe other operations present only in the ranges header, which is much better for composability:
#include <ranges>
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
const auto v = std::vector{ 1, 2, 3, 4, 5 };
const auto is_odd = [](const auto n){ return n % 2 == 1; };
const auto square = [](const auto n){ return n * n; };
const auto print = [](const auto n){ std::cout << n << " ";};
std::ranges::for_each(
v | std::ranges::views::filter(is_odd) | std::ranges::views::transform(square),
print); // prints: 1 9 25
}
Upvotes: 9