Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++20 ranges and sorting

I'm dealing with the last big 4 of C++ 20, attempting to learn the new main features. Trying some code from the web related to ranges, I've written:

std::vector ints{ 6, 5, 2, 8 };
auto even = [](int i) {
    return 0 == i % 2;
};

// ranges...
auto rr = ints | std::views::filter(even) 
               | std::views::transform([](auto i) {
                   return i * i;
                 })
               | std::views::reverse;

Then I would sort, like range-v3 does with |action::sort, but I've understand that this implementation is not the same.

The way I've found to sort is:

ints = std::vector(std::ranges::begin(rr), std::ranges::end(rr));
std::ranges::sort(ints);

Am I wrong? Does anybody know how to sort with pipe style the view ?

like image 423
Chris Avatar asked Sep 28 '20 12:09

Chris


People also ask

What are C ++ 20 ranges?

ranges::range. (C++20) specifies that a type is a range, that is, it provides a begin iterator and an end sentinel. (concept)

How do ranges work C++?

Range - Ranges are an abstraction that allows a C++ program to operate on elements of data structures uniformly. On minimum a range contains defines begin() and end() to elements. There are several different types of ranges: containers, views, sized ranges, Container - It's a range that owns the elements.

Is std::sort stable?

As of September 2020, it appears that libc++ std::sort happens to be stable for all ranges of size less than 31, and libstdc++ std::sort happens to be stable for all ranges of size less than 17. (Do not rely on this little factoid in production!) To be clear: There's nothing wrong with this.

How is std::sort implemented?

The std::sort is a sorting function that uses the Introsort algorithm and have the complexity of O(N log(N)) where N= std::distance(first, last) since C++11 and the order of equal elements is not guaranteed to be preserved[3]. The gcc-libstdc++ also uses Introsort algorithm.

Is there a range algorithm in c++ 20?

As of C++20, there are no numerical ranges algorithms corresponding to the <numeric> header. Below, you can find examples showing a standard algorithm and an alternative version with ranges. They illustrate some basic concepts and try not to use advanced ranges composition or views.

What is ranges library in c++ 20?

Ranges library (C++20) Ranges library. (C++20) The ranges library provides components for dealing with ranges of elements, including a variety of view adapters. The namespace alias std::views is provided as a shorthand for std::ranges::views .

What is the use of ranges in C++?

The ranges library provides components for dealing with ranges of elements, including a variety of view adapters. The namespace alias std::views is provided as a shorthand for std::ranges::views . Some range adaptors wrap their elements or function objects with the copyable wrapper .

What is the difference between c++20 and C++23?

As of C++20, we have most of the corresponding ranges algorithms from the <algorithm> header, but the <numeric> header is missing. C++23 specification is almost complete and in the feature-freeze mode. So far I’m aware of the following algorithms that we’ll land in the new C++ version:


1 Answers

Then I would sort, like range-v3 does with |action::sort ...

No, you can't actually sort rr like this:

rr |= ranges::actions::sort; // error

because rr is a view. While views can provide mutable access to the underlying range, sort additionally needs the range to support random access. A lazily generated view like rr does not allow this.

You can create a vector from rr as you have done, and then you can use actions on that range:

ints |= ranges::actions::sort;  // ok

c++20, however, doesn't have any actions (hopefully we'll get them in c++23), so until then you'll have to call the algorithm sort without the pipe syntax:

std::ranges::sort(ints);  // ok
like image 62
cigien Avatar answered Oct 30 '22 00:10

cigien