{"id":5854,"date":"2020-02-17T12:01:10","date_gmt":"2020-02-17T12:01:10","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-functional-patterns-with-the-ranges-library\/"},"modified":"2023-09-27T16:55:16","modified_gmt":"2023-09-27T16:55:16","slug":"c-20-functional-patterns-with-the-ranges-library","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-functional-patterns-with-the-ranges-library\/","title":{"rendered":"C++20: Functional Patterns with the Ranges Library"},"content":{"rendered":"<p>My last post <a href=\"http:\/\/bit.ly\/2V8Fbqz\">C++20: The Ranges Library<\/a>, gave you the first impression of the ranges library. Today&#8217;s post is about functional patterns: function composition and lazy evaluation. They become first-class citizens in C++20.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8380 size-full\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/TimelineCpp20Ranges.png\" alt=\"\" width=\"979\" height=\"373\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/TimelineCpp20Ranges.png 979w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/TimelineCpp20Ranges-300x114.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/TimelineCpp20Ranges-768x293.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/TimelineCpp20Ranges-705x269.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/TimelineCpp20Ranges-845x321.png 845w\" sizes=\"auto, (max-width: 979px) 100vw, 979px\" \/><\/p>\n<p>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.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #009999;\">#include &lt;numeric&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n    \n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myVec{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">7<\/span>, <span style=\"color: #ff6600;\">8<\/span>, <span style=\"color: #ff6600;\">9<\/span>};\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> res <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>accumulate(std<span style=\"color: #555555;\">::<\/span>begin(myVec), std<span style=\"color: #555555;\">::<\/span>end(myVec), <span style=\"color: #ff6600;\">0<\/span>); \n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::accumulate(myVec, 0);                                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> res <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;      <span style=\"color: #0099ff; font-style: italic;\">\/\/  45 <\/span>\n    \n}\n<\/pre>\n<\/div>\n<p>Would it be nice if <span style=\"font-family: 'courier new', courier;\">std::accumulate<\/span> could be executed directly on the container, such as in line (2)?<\/p>\n<h2>Direct on the Container<\/h2>\n<p>The following program creates direct views on the keys (line 1) and the values (line\u00a0 3) of the <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span>.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ rangesEntireContainer.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;ranges&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;unordered_map&gt;<\/span>\n\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n    \n    std<span style=\"color: #555555;\">::<\/span>unordered_map<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> freqWord{ {<span style=\"color: #cc3300;\">\"witch\"<\/span>, <span style=\"color: #ff6600;\">25<\/span>}, {<span style=\"color: #cc3300;\">\"wizard\"<\/span>, <span style=\"color: #ff6600;\">33<\/span>}, {<span style=\"color: #cc3300;\">\"tale\"<\/span>, <span style=\"color: #ff6600;\">45<\/span>},\n                                                   {<span style=\"color: #cc3300;\">\"dog\"<\/span>, <span style=\"color: #ff6600;\">4<\/span>}, {<span style=\"color: #cc3300;\">\"cat\"<\/span>, <span style=\"color: #ff6600;\">34<\/span>}, {<span style=\"color: #cc3300;\">\"fish\"<\/span>, <span style=\"color: #ff6600;\">23<\/span>} };\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Keys\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> names <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord);                                            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name <span style=\"color: #555555;\">:<\/span> names){ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; };\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord)){ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; };   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Values: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> values <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>values(freqWord);                                          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> value <span style=\"color: #555555;\">:<\/span> values){ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> value <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; };\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> value <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>values(freqWord)){ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> value <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; } <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\n                           \n}\n<\/pre>\n<\/div>\n<p>Of course, the keys and values can be displayed directly (lines 2 and line 4). The output is identical.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5851\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesEntireContainer.png\" alt=\"rangesEntireContainer\" width=\"302\" height=\"219\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesEntireContainer.png 302w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesEntireContainer-300x218.png 300w\" sizes=\"auto, (max-width: 302px) 100vw, 302px\" \/><\/p>\n<p>Working directly on the container is not revolutionary, but function composition and lazy evaluation are.<\/p>\n<h2>Function Composition<\/h2>\n<p>In my following example, I use<span style=\"font-family: 'courier new', courier;\"> std::map<\/span> because the ordering of the keys is crucial.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ rangesComposition.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;ranges&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;map&gt;<\/span>\n\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n    \n    std<span style=\"color: #555555;\">::<\/span>map<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> freqWord{ {<span style=\"color: #cc3300;\">\"witch\"<\/span>, <span style=\"color: #ff6600;\">25<\/span>}, {<span style=\"color: #cc3300;\">\"wizard\"<\/span>, <span style=\"color: #ff6600;\">33<\/span>}, {<span style=\"color: #cc3300;\">\"tale\"<\/span>, <span style=\"color: #ff6600;\">45<\/span>},\n                                                   {<span style=\"color: #cc3300;\">\"dog\"<\/span>, <span style=\"color: #ff6600;\">4<\/span>}, {<span style=\"color: #cc3300;\">\"cat\"<\/span>, <span style=\"color: #ff6600;\">34<\/span>}, {<span style=\"color: #cc3300;\">\"fish\"<\/span>, <span style=\"color: #ff6600;\">23<\/span>} };\n                                                \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"All words: \"<\/span>;                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord)) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; };                                               \n                                                   \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"All words reverse: \"<\/span>;             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>reverse) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; };  \n     \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"The first 4 words: \"<\/span>;             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>take(<span style=\"color: #ff6600;\">4<\/span>)) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; }; \n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n                                \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"All words starting with w: \"<\/span>;     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> firstw <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> name){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> name[<span style=\"color: #ff6600;\">0<\/span>] <span style=\"color: #555555;\">==<\/span> <span style=\"color: #cc3300;\">'w'<\/span>; };\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>filter(firstw)) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>; };\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n                                                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> lengthOf <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> name){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> name.size(); };\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> res <span style=\"color: #555555;\">=<\/span> ranges<span style=\"color: #555555;\">::<\/span>accumulate(std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>transform(lengthOf), <span style=\"color: #ff6600;\">0<\/span>);\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Sum of words: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> res <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n   \n}\n<\/pre>\n<\/div>\n<p>In this case, I&#8217;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 &#8216;w&#8217; (line 4). Line (5) sums up all the lengths of all words.<\/p>\n<p>The pipe symbol | is <a href=\"https:\/\/en.wikipedia.org\/wiki\/Syntactic_sugar\">syntactic sugar<\/a> for function composition. Instead of <span style=\"font-family: 'courier new', courier;\">C(R)<\/span>, you can write <span style=\"font-family: 'courier new', courier;\">R | C<\/span>. Consequentially, the following two lines are equivalent.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\"><span style=\"color: #006699; font-weight: bold;\">auto<\/span> <\/span><span style=\"color: #006699;\"><span style=\"color: #000000;\">rev2<\/span><\/span><span style=\"color: #006699; font-weight: bold;\"> <span style=\"color: #555555;\">=<\/span> <\/span><span style=\"color: #006699;\"><span style=\"color: #000000;\">std::views::reverse(ranges::views::keys(freqWord));<\/span><\/span><span style=\"color: #006699; font-weight: bold;\">\nauto<\/span> rev <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>keys(freqWord) <span style=\"color: #555555;\">|<\/span> ranges<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>reverse; \n<\/pre>\n<\/div>\n<p>Finally, here is the output of the program.<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5852\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesComposition.png\" alt=\"rangesComposition\" width=\"409\" height=\"193\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesComposition.png 409w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesComposition-300x142.png 300w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/p>\n<h2><span style=\"color: inherit;\">Lazy Evaluation<\/span><\/h2>\n<p>I use in my example <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/ranges\/iota_view\">std::views::iota<\/a>. 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 <span style=\"font-family: 'courier new', courier;\">std::vector<\/span> with ten <span style=\"font-family: 'courier new', courier;\">int&#8217;s<\/span>, starting with 0.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ rangesIota.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;numeric&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;ranges&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha;\n    \n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> vec;\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> vec2;\n    \n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(<span style=\"color: #ff6600;\">0<\/span>, <span style=\"color: #ff6600;\">10<\/span>)) vec.push_back(i);                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)         <\/span>\n         \n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(<span style=\"color: #ff6600;\">0<\/span>) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>take(<span style=\"color: #ff6600;\">10<\/span>)) vec2.push_back(i);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"vec == vec2: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> (vec <span style=\"color: #555555;\">==<\/span> vec2) <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; <span style=\"color: #0099ff; font-style: italic;\">\/\/ true<\/span>\n    \n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> vec) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;                <span style=\"color: #0099ff; font-style: italic;\">\/\/ 0 1 2 3 4 5 6 7 8 9<\/span>\n                           \n}\n<\/pre>\n<\/div>\n<p>The first <span style=\"font-family: 'courier new', courier;\">iota<\/span> call (line 1) creates all numbers from 0 to 9, incremented by 1. The second <span style=\"font-family: 'courier new', courier;\">iota<\/span> call (line 2) creates an infinite data stream, starting with 0 and incremented by 1. <span style=\"font-family: 'courier new', courier;\">std::views::iota(0)<\/span> is lazy. I only get a new value if I ask for it. I asked for it ten times. Consequentially, both vectors are identical.<\/p>\n<p>Now,\u00a0 I want to solve a small challenge. I want to find the first 20 prime numbers, starting with 1000000.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ rangesLazy.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;ranges&gt;<\/span>\n\n\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #cc00ff;\">isPrime<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> i) {\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> j<span style=\"color: #555555;\">=<\/span><span style=\"color: #ff6600;\">2<\/span>; j<span style=\"color: #555555;\">*<\/span>j <span style=\"color: #555555;\">&lt;=<\/span> i; <span style=\"color: #555555;\">++<\/span>j){\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> (i <span style=\"color: #555555;\">%<\/span> j <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">false<\/span>;\n    }\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">true<\/span>;\n}\n\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\n                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Numbers from 1000000 to 1001000 (dispayed each 100th): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(<span style=\"color: #ff6600;\">1000000<\/span>, <span style=\"color: #ff6600;\">1001000<\/span>)) {\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> (i <span style=\"color: #555555;\">%<\/span> <span style=\"color: #ff6600;\">100<\/span> <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span>) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;  \n    }\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> odd <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #007788; font-weight: bold;\">int<\/span> i){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">%<\/span> <span style=\"color: #ff6600;\">2<\/span> <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">1<\/span>; };\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Odd numbers from 1000000 to 1001000 (displayed each 100th): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(<span style=\"color: #ff6600;\">1000000<\/span>, <span style=\"color: #ff6600;\">1001000<\/span>) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>filter(odd)) {\n         <span style=\"color: #006699; font-weight: bold;\">if<\/span> (i <span style=\"color: #555555;\">%<\/span> <span style=\"color: #ff6600;\">100<\/span> <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">1<\/span>) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;  \n    }\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n                                         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Prime numbers from 1000000 to 1001000: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(<span style=\"color: #ff6600;\">1000000<\/span>, <span style=\"color: #ff6600;\">1001000<\/span>) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>filter(odd) \n                                                   <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>filter(isPrime)) {\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;  \n    }\n    \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n                                         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"20 prime numbers starting with 1000000: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(<span style=\"color: #ff6600;\">1000000<\/span>) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>filter(odd) \n                                          <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>filter(isPrime) \n                                          <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>take(<span style=\"color: #ff6600;\">20<\/span>)) {\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;  \n    }\n\n}\n<\/pre>\n<\/div>\n<p>Here is my iterative strategy:<\/p>\n<ol>\n<li>Of course, I don&#8217;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.<\/li>\n<li>I&#8217;m only interested in the odd numbers; therefore, I removed the even numbers.<\/li>\n<li>Now, it&#8217;s time to apply the next filter. The predicate <span style=\"font-family: 'courier new', courier;\">isPrime<\/span> returns if a number is a prime. As you can see in the following screenshot, I was too eager. I got 75 primes.<\/li>\n<li>Laziness is a virtue. I use <span style=\"font-family: 'courier new', courier;\">std::iota<\/span> as an infinite number factory, starting with 1000000, and ask precisely for 20 primes.<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5853\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesLazy.png\" alt=\"rangesLazy\" width=\"650\" height=\"177\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesLazy.png 1164w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesLazy-300x82.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesLazy-1024x279.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/rangesLazy-768x209.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Python has many very nice functions, such as <span style=\"font-family: 'courier new', courier;\">range<\/span>, <span style=\"font-family: 'courier new', courier;\">map<\/span>, <span style=\"font-family: 'courier new', courier;\">filter<\/span>, <span style=\"font-family: 'courier new', courier;\">reduce, <\/span>and<span style=\"font-family: 'courier new', courier;\"> zip.<\/span>\u00a0And, of course, there is also the slice operator and list comprehension. These functions are eager in Python 2, but <span style=\"font-family: 'courier new', courier;\">map<\/span>, <span style=\"font-family: 'courier new', courier;\">filter<\/span>, and <span style=\"font-family: 'courier new', courier;\">reduce<\/span> are lazy in Python 3. I will try an experiment in my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-pythonic-with-the-ranges-library\">next post.<\/a> Which functions can I implement with similar functionality in C++ by using the ranges library?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My last post C++20: The Ranges Library, gave you the first impression of the ranges library. Today&#8217;s post is about functional patterns: function composition and lazy evaluation. They become first-class citizens in C++20.<\/p>\n","protected":false},"author":21,"featured_media":8380,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[413],"class_list":["post-5854","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-ranges"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5854","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5854"}],"version-history":[{"count":2,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5854\/revisions"}],"predecessor-version":[{"id":8391,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5854\/revisions\/8391"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/8380"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5854"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}