My last post C++20: The Ranges Library, gave you the first impression of the ranges library. Today’s post is about functional patterns: function composition and lazy evaluation. They become first-class citizens in C++20.
The Standard Template Library (STL) algorithms are sometimes a little inconvenient. They need a beginning and an end iterator. This is often more than you want to write.
Would it be nice if std::accumulate could be executed directly on the container, such as in line (2)?
Direct on the Container
The following program creates direct views on the keys (line 1) and the values (line 3) of the std::unordered_map.
Of course, the keys and values can be displayed directly (lines 2 and line 4). The output is identical.
Working directly on the container is not revolutionary, but function composition and lazy evaluation are.
In my following example, I use std::map because the ordering of the keys is crucial.
In this case, I’m only interested in the keys. I display all of them (line 1), all of them reversed (line 2), the first four (line 3), and the keys starting with the letter ‘w’ (line 4). Line (5) sums up all the lengths of all words.
The pipe symbol | is syntactic sugar for function composition. Instead of C(R), you can write R | C. Consequentially, the following two lines are equivalent.
Finally, here is the output of the program.
I use in my example std::views::iota. This function is a range factory for creating a sequence of elements by successively incrementing an initial value. This sequence can be finite or infinite. The following example fills a std::vector with ten int’s, starting with 0.
The first iota call (line 1) creates all numbers from 0 to 9, incremented by 1. The second iota call (line 2) creates an infinite data stream, starting with 0 and incremented by 1. std::views::iota(0) is lazy. I only get a new value if I ask for it. I asked for it ten times. Consequentially, both vectors are identical.
Now, I want to solve a small challenge. I want to find the first 20 prime numbers, starting with 1000000.
Here is my iterative strategy:
- Of course, I don’t know when I have 20 primes greater than 1000000. To be on the safe side, I create 1000 numbers. For obvious reasons, I displayed only each 100th.
- I’m only interested in the odd numbers; therefore, I removed the even numbers.
- Now, it’s time to apply the next filter. The predicate isPrime returns if a number is a prime. As you can see in the following screenshot, I was too eager. I got 75 primes.
- Laziness is a virtue. I use std::iota as an infinite number factory, starting with 1000000, and ask precisely for 20 primes.
Python has many very nice functions, such as range, map, filter, reduce, and zip. And, of course, there is also the slice operator and list comprehension. These functions are eager in Python 2, but map, filter, and reduce are lazy in Python 3. I will try an experiment in my next post. Which functions can I implement with similar functionality in C++ by using the ranges library?
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, and Marco Parri Empoli.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,