{"id":8541,"date":"2023-10-30T09:15:20","date_gmt":"2023-10-30T09:15:20","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=8541"},"modified":"2023-10-30T09:15:20","modified_gmt":"2023-10-30T09:15:20","slug":"the-ranges-library-in-c20-design-choices","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-ranges-library-in-c20-design-choices\/","title":{"rendered":"The Ranges Library in C++20: Design Choices"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Thanks to the ranges library, working with the Standard Template Library (STL) is much more comfortable and powerful. First of all,  the algorithms of the ranges library are lazy, can work directly on the container, and can be composed. Additionally, the ranges library made a few unique design choices, you must know.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"979\" height=\"373\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/TimelineCpp20Ranges.png\" alt=\"\" class=\"wp-image-8543\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/TimelineCpp20Ranges.png 979w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/TimelineCpp20Ranges-300x114.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/TimelineCpp20Ranges-768x293.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/TimelineCpp20Ranges-705x269.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/TimelineCpp20Ranges-845x321.png 845w\" sizes=\"auto, (max-width: 979px) 100vw, 979px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Before I dive deep into the ranges library in C++20, I want to recap in a few sentences the three main features of the ranges: The algorithms of the ranges can directly operate on the container, evaluate their arguments lazily, and can be composed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Direct on the Container<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The ranges library enables a container such as <code>std::ranges::sort<\/code> can directly operate on the container:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ sortRanges.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;algorithm&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: #555555\">-<\/span><span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #FF6600\">0<\/span>, <span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">4<\/span>};\n    std<span style=\"color: #555555\">::<\/span>ranges<span style=\"color: #555555\">::<\/span>sort(myVec);                  <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\">auto<\/span> v<span style=\"color: #555555\">:<\/span> myVec) std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> v <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot; &quot;<\/span>; <span style=\"color: #0099FF; font-style: italic\">\/\/ -4, -3, 0, 5, 7<\/span>\n\n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">On the contrary, the classic std::sort operates on a range defined by two iterators: <code>std:sort(myVec.begin(), myVec.end()<\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The ranges algorithms are lazy and can be composed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lazy Evaluation and Function Composition<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The following program <code>primesLazy.cpp<\/code> applies both features. It creates the first ten prime numbers, starting with one million.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ primesLazy.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                                        \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n                                         \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\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\">1<\/span><span style=\"color: #AA0000; background-color: #FFAAAA\">&#39;<\/span><span style=\"color: #FF6600\">000<\/span><span style=\"color: #AA0000; background-color: #FFAAAA\">&#39;<\/span><span style=\"color: #FF6600\">000<\/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\">10<\/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\">&quot; &quot;<\/span>;  \n    }\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">You have to read the function composition from left to right: I create an infinite data stream starting with 1\u2019000\u2019000 (<code>std::views::iota(1'000'000)<\/code>) and apply two filters. Each filter needs a predicate. The first filter let odd elements pass (<code>std::views::filter(odd)<\/code>), and the second filter lets the prime numbers pass (<code>std::views::filter(isPrime)<\/code>). To end the infinite data stream, I stop after ten numbers (<code>std::views::take(10)<\/code>).&nbsp; Finally, here are the first ten prime numbers starting with one million.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"808\" height=\"190\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/primesLazy.png\" alt=\"\" class=\"wp-image-8547\" style=\"width:600px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/primesLazy.png 808w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/primesLazy-300x71.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/primesLazy-768x181.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/primesLazy-705x166.png 705w\" sizes=\"auto, (max-width: 808px) 100vw, 808px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You may ask: Who starts the processing of this data pipeline? Now, it goes from right to left. The data sink (<code>std::views::take(10)<\/code>) want to have the next value and ask its predecessor. This request continues until the range-based for-loop produces the next value. The range-based for-loop can produce an infinite data stream, but it only produces values on request. This is lazy evaluation. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This was my short recap. When you want to read more about the ranges library, including sentinels, projection, and concepts,  read my previous posts:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"http:\/\/bit.ly\/2V8Fbqz\">The Ranges Library<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/bit.ly\/32iY77s\">Functional Pattern with the Ranges Library<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-ranges-library-in-c-20-a-deep-dive\">The Ranges Library in C++20: More Details<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/projections-with-ranges\">Projections with Ranges<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/sentinels-and-concepts\">Sentinels and Concepts with Ranges Algorithms<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/improved-iterators-with-ranges\">Improved Iterators with Ranges<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/bit.ly\/2TyfqNX\">Pythonic with the Ranges Library<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/bit.ly\/2wI2z3G\">Pythons range Function, the Second<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/bit.ly\/2QhUQAw\">Pythons map Function<\/a><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let me write about something new.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Design Choices<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For efficiency reasons, the ranges library has some unique design choices. It&#8217;s important to know and follow theses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you study the <code>begin <\/code>member function of <code>std::ranges::filter_view<\/code>, you find code equivalent to the following one:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #006699; font-weight: bold\">if<\/span> constexpr (<span style=\"color: #555555\">!<\/span>ranges<span style=\"color: #555555\">::<\/span>forward_range<span style=\"color: #555555\">&lt;<\/span>V<span style=\"color: #555555\">&gt;<\/span>)\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> <span style=\"color: #0099FF; font-style: italic\">\/* iterator *\/<\/span>{<span style=\"color: #555555\">*<\/span><span style=\"color: #006699; font-weight: bold\">this<\/span>, ranges<span style=\"color: #555555\">::<\/span>find_if(base_, std<span style=\"color: #555555\">::<\/span>ref(<span style=\"color: #555555\">*<\/span>pred_))};\n<span style=\"color: #006699; font-weight: bold\">else<\/span>\n{\n    <span style=\"color: #006699; font-weight: bold\">if<\/span> (<span style=\"color: #555555\">!<\/span>begin_.has_value())\n        begin_ <span style=\"color: #555555\">=<\/span> ranges<span style=\"color: #555555\">::<\/span>find_if(base_, std<span style=\"color: #555555\">::<\/span>ref(<span style=\"color: #555555\">*<\/span>pred_)); <span style=\"color: #0099FF; font-style: italic\">\/\/ caching<\/span>\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> <span style=\"color: #0099FF; font-style: italic\">\/* iterator *\/<\/span>{<span style=\"color: #555555\">*<\/span><span style=\"color: #006699; font-weight: bold\">this<\/span>, begin_.value())};\n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s analyze the nested <code>if <\/code>clause. First, the compiler checks if <code>begin_.has_value() <\/code>is <code>true<\/code>. If not, it determines <code>begin_<\/code>. This means that this member function caches the result within the <code>std::ranges::filter_view<\/code> object for use on subsequent calls. This caching has interesting consequences. Let me exemplify this with a code snippet.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ cachingRanges.cpp<\/span>\n\n<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;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>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> vec(<span style=\"color: #FF6600\">1<\/span><span style=\"color: #AA0000; background-color: #FFAAAA\">&#39;<\/span><span style=\"color: #FF6600\">000<\/span><span style=\"color: #AA0000; background-color: #FFAAAA\">&#39;<\/span><span style=\"color: #FF6600\">000<\/span>);\n    std<span style=\"color: #555555\">::<\/span>iota(vec.begin(), vec.end(), <span style=\"color: #FF6600\">0<\/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 <span style=\"color: #555555\">|<\/span> std<span style=\"color: #555555\">::<\/span>views<span style=\"color: #555555\">::<\/span>filter([](<span style=\"color: #006699; font-weight: bold\">auto<\/span> v) { <span style=\"color: #006699; font-weight: bold\">return<\/span> v <span style=\"color: #555555\">&gt;<\/span> <span style=\"color: #FF6600\">1000<\/span>; }) \n                    <span style=\"color: #555555\">|<\/span> std<span style=\"color: #555555\">::<\/span>views<span style=\"color: #555555\">::<\/span>take(<span style=\"color: #FF6600\">5<\/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\">&quot; &quot;<\/span>;  <span style=\"color: #0099FF; font-style: italic\">\/\/ 1001 1002 1003 1004 1005<\/span>\n                    }\n    \n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The first call of <code>std::views::filter([](auto v) { return v &gt; 1000; })<\/code> determines the begin iterator and reuses it in subsequent calls. The benefit of this caching is obvious. Many subsequent iterations of the pipeline are spared. But there are also severe drawbacks: cache issues and constness issues.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cache<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here are the two important cache rules for ranges:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Don&#8217;t use a view on modified ranges.<\/li>\n\n\n\n<li>Don&#8217;t copy a view.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Let me play with the previous program <code>cachingRanges.cpp<\/code> and break both rules:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ cachingIssuesRanges.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;concepts&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;forward_list&gt;<\/span>\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\">void<\/span> <span style=\"color: #CC00FF\">printElements<\/span>(std<span style=\"color: #555555\">::<\/span>ranges<span style=\"color: #555555\">::<\/span>input_range <span style=\"color: #006699; font-weight: bold\">auto<\/span><span style=\"color: #555555\">&amp;&amp;<\/span> rang) {\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> rang) {\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\">&quot; &quot;<\/span>;  \n    }\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/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>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/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> vec{<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">10<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">9<\/span>, <span style=\"color: #FF6600\">0<\/span>, <span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">5<\/span>};                            <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n    std<span style=\"color: #555555\">::<\/span>forward_list<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> forL{<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">10<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">9<\/span>, <span style=\"color: #FF6600\">0<\/span>, <span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">5<\/span>};                     <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> first5Vector <span style=\"color: #555555\">=<\/span> vec <span style=\"color: #555555\">|<\/span> std<span style=\"color: #555555\">::<\/span>views<span style=\"color: #555555\">::<\/span>filter([](<span style=\"color: #006699; font-weight: bold\">auto<\/span> v) { <span style=\"color: #006699; font-weight: bold\">return<\/span> v <span style=\"color: #555555\">&gt;<\/span> <span style=\"color: #FF6600\">0<\/span>; })   <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n                            <span style=\"color: #555555\">|<\/span> std<span style=\"color: #555555\">::<\/span>views<span style=\"color: #555555\">::<\/span>take(<span style=\"color: #FF6600\">5<\/span>);\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> first5ForList <span style=\"color: #555555\">=<\/span> forL <span style=\"color: #555555\">|<\/span> std<span style=\"color: #555555\">::<\/span>views<span style=\"color: #555555\">::<\/span>filter([](<span style=\"color: #006699; font-weight: bold\">auto<\/span> v) { <span style=\"color: #006699; font-weight: bold\">return<\/span> v <span style=\"color: #555555\">&gt;<\/span> <span style=\"color: #FF6600\">0<\/span>; }) <span style=\"color: #0099FF; font-style: italic\">\/\/ (4) <\/span>\n                              <span style=\"color: #555555\">|<\/span> std<span style=\"color: #555555\">::<\/span>views<span style=\"color: #555555\">::<\/span>take(<span style=\"color: #FF6600\">5<\/span>);            \n\n    printElements(first5Vector);           <span style=\"color: #0099FF; font-style: italic\">\/\/ 10 4 9 5                           \/\/ (5)<\/span>\n    printElements(first5ForList);          <span style=\"color: #0099FF; font-style: italic\">\/\/ 10 4 9 5                           \/\/ (6)<\/span>\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    vec.insert(vec.begin(), <span style=\"color: #FF6600\">10<\/span>);\n    forL.insert_after(forL.before_begin(), <span style=\"color: #FF6600\">10<\/span>);\n\n\n    printElements(first5Vector);           <span style=\"color: #0099FF; font-style: italic\">\/\/ -3 10 4 9 5<\/span>\n    printElements(first5ForList);          <span style=\"color: #0099FF; font-style: italic\">\/\/ 10 4 9 5<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> first5VectorCopy{first5Vector};                                        <span style=\"color: #0099FF; font-style: italic\">\/\/ (7)<\/span>\n    <span style=\"color: #006699; font-weight: bold\">auto<\/span> first5ForListCopy{first5ForList};                                      <span style=\"color: #0099FF; font-style: italic\">\/\/ (8)<\/span>\n\n    printElements(first5VectorCopy);       <span style=\"color: #0099FF; font-style: italic\">\/\/ -3 10 4 9 5<\/span>\n    printElements(first5ForListCopy);      <span style=\"color: #0099FF; font-style: italic\">\/\/ 10 10 4 9 5<\/span>\n    \n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n}\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To make it easier to follow the problem, I wrote the output directly in the source code. The program does the following steps with a <code>std::vector <\/code>and a <code>std::forward_list<\/code>. First, both containers are initialized with the initializer list <code>{-3, 10, 4, -7, 9, 0, 5, -5<\/code>} (lines 1 and 2). Then, I create two views (lines 3 and 4). Both views <code>first5Vector<\/code> and <code>first5ForList<\/code> consist of the first 5 elements greater than 0. Lines (5) and (6) display the corresponding values.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, I break the first rule: &#8220;Don&#8217;t use a view on modified ranges.&#8221; I insert <code>10<\/code> at the beginning of both containers. Afterward, <code>first5Vector<\/code> displays the <code>-3<\/code> and <code>first5ForList<\/code> ignores the added <code>10<\/code>. &nbsp;After the break of the second rule, &#8220;Don&#8217;t copy a view.&#8221; in lines (7) and (8), the cache of <code>first5ForListCopy<\/code> is invalidated. <code>first5VectorCopy<\/code> still shows the wrong numbers. Finally, here is the output of the program.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"443\" height=\"363\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/cachingIssuesRanges.png\" alt=\"\" class=\"wp-image-8563\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/cachingIssuesRanges.png 443w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/10\/cachingIssuesRanges-300x246.png 300w\" sizes=\"auto, (max-width: 443px) 100vw, 443px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a simple rule of thumb: <strong>Use views directly after you have defined them.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You may have noticed that the function <code>printElements<\/code> takes it arguments by universal reference, aka forwarding reference.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s next?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"> Let me write in my next post, why a function should take an arbitrary view by universal reference.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Here is a Note on my Behalf<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I am sorry to inform you that I have ALS, a very serious progressive nerve condition. Therefore, I am unsure how long I can continue this blog. Currently, I can only travel to trainings or conferences with the help of my wife. We (my family and I) have decided to deal aggressively with this challenge. Therefore, it was important for me to let you, my loyal readers, in on my illness.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Additionally, if you know anything about a clinical trial or some new treatment, please write me an e-mail. In Germany, the only medicament is Riluzol.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modernes C++<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"222\" height=\"67\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/07\/RainerGrimmDunkelBlauSmall.jpg\" alt=\"\" class=\"wp-image-7937\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Thanks to the ranges library, working with the Standard Template Library (STL) is much more comfortable and powerful. First of all, the algorithms of the ranges library are lazy, can work directly on the container, and can be composed. Additionally, the ranges library made a few unique design choices, you must know. Before I dive [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":8543,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[413],"class_list":["post-8541","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\/8541","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=8541"}],"version-history":[{"count":19,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8541\/revisions"}],"predecessor-version":[{"id":8582,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/8541\/revisions\/8582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/8543"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=8541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=8541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=8541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}