{"id":6370,"date":"2022-05-31T19:36:30","date_gmt":"2022-05-31T19:36:30","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/sentinels-and-concepts\/"},"modified":"2023-09-27T16:56:59","modified_gmt":"2023-09-27T16:56:59","slug":"sentinels-and-concepts","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/sentinels-and-concepts\/","title":{"rendered":"Sentinels and Concepts with Ranges Algorithms"},"content":{"rendered":"<p>The ranges library in C++20 supports sentinels. Sentinels stand for the end of a range and can be regarded as generalized end iterators.<\/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>A range provided by a begin iterator and an end sentinel specifies a group of items you can iterate over. The containers of the STL are ranges because their end iterator marks the end of the range.<\/p>\n<h2>Sentinel<\/h2>\n<div>\n<div>The following example uses sentinels for a C-string and a <code>std::vector&lt;int&gt;<\/code>.<\/div>\n<div><\/div>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ sentinel.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;compare&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Space {                       <em><span style=\"color: #0099ff;\"> \/\/ (1)<\/span><\/em>\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> pos) <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span>pos <span style=\"color: #555555;\">==<\/span> <span style=\"color: #cc3300;\">' '<\/span>; \n    }\n};\n\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> NegativeNumber {              <em><span style=\"color: #0099ff;\"> \/\/ (2)<\/span><\/em>\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> num) <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">*<\/span>num <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">0<\/span>;   \n    }\n};\n\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Sum {                          <em><span style=\"color: #0099ff;\">\/\/ (7)<\/span><\/em>\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span>()(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> n) { sum <span style=\"color: #555555;\">+=<\/span> n; }\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> sum{<span style=\"color: #ff6600;\">0<\/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;\">'\\n'<\/span>;\n\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">char<\/span><span style=\"color: #555555;\">*<\/span> rainerGrimm <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"Rainer Grimm\"<\/span>;\n   \n    std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>for_each(rainerGrimm, Space{}, [] (<span style=\"color: #007788; font-weight: bold;\">char<\/span> c) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> c; });  <span style=\"color: #0099ff;\">\/\/ (3)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> c<span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>subrange{rainerGrimm, Space{}}) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> c;     <span style=\"color: #0099ff;\"> \/\/ (4)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\n\n    std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>subrange rainer{rainerGrimm, Space{}};                           <span style=\"color: #0099ff;\"> \/\/ (5)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>for_each(rainer, [] (<span style=\"color: #007788; font-weight: bold;\">char<\/span> c) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> c <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">' '<\/span>; });        <span style=\"color: #0099ff;\"> \/\/ (6)<\/span>\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> c<span style=\"color: #555555;\">:<\/span> rainer) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> c <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> <span style=\"color: #cc3300;\">'\\n'<\/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<\/span><span style=\"color: #cc3300;\">\"<\/span>;\n\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;\">5<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">33<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">10<\/span>};\n\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;\">\" \"<\/span>;\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\n\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> [tmp1, sum] <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>for_each(myVec, Sum{});\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Sum: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> sum.sum <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;                                   <em><span style=\"color: #0099ff;\">\/\/ (8)<\/span>\n<\/em>\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> [tmp2, sum2] <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>for_each(std<span style=\"color: #555555;\">::<\/span>begin(myVec), NegativeNumber{}, \n                                              Sum{} );            \n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Sum: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> sum2.sum <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;                                   <em><span style=\"color: #0099ff;\">\/\/ (9)<\/span><\/em>\n\n    std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>transform(std<span style=\"color: #555555;\">::<\/span>begin(myVec), NegativeNumber{},              <em> <span style=\"color: #0099ff;\">  \/\/ (10)<\/span><\/em>\n                           std<span style=\"color: #555555;\">::<\/span>begin(myVec), [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> num) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> num <span style=\"color: #555555;\">*<\/span> num; });\n    std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>for_each(std<span style=\"color: #555555;\">::<\/span>begin(myVec), NegativeNumber{},                <em><span style=\"color: #0099ff;\">  \/\/ (11)<\/span><\/em>\n                          [](<span style=\"color: #007788; font-weight: bold;\">int<\/span> num) { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> num <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> <span style=\"color: #cc3300;\">'\\n'<\/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> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>subrange{ std<span style=\"color: #555555;\">::<\/span>begin(myVec), NegativeNumber{}}) { <em><span style=\"color: #0099ff;\">\/\/ (12)<\/span><\/em>\n        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;\">\" \"<\/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    \n}\n<\/pre>\n<\/div>\n<\/div>\n<div>\n<div>The program defines two sentinels: Space (line 1) and <code>NegativeNumber<\/code> (line 2). Both define the equal operator. Thanks to the <code>&lt;compare&gt;<\/code> header, the compiler auto-generates the non-equal operator. The non-equal operator is required when using algorithms such as <code>std::ranges_for_each<\/code> or <code>std::ranges::transform<\/code> with a sentinel. Let me start with the sentinel <code>Space<\/code>.<\/div>\n<div>Line (3) applies the sentinel <code>Space{}<\/code> directly onto the string &#8220;<code>rainerGrimm<\/code>&#8220;. Creating a <code>std::ranges::subrange<\/code> (line 4) allows it to use the sentinel in a range-based for-loop. You can also define a <code>std::ranges::subrange<\/code> and use it directly in the algorithm std::ranges::for_each (line 5) or in a range-based for-loop (line 6).<\/div>\n<div>My second example uses a <code>std::vector&lt;int&gt;<\/code>, filled with the values <code>{5, 10, 33, -5, 10}<\/code>. The sentinel <code>NegativeNumber<\/code> checks if a number is negative. First, I sum up all values using the function object <code>Sum<\/code> (line 7). <code>std::ranges::for_each<\/code> returns a pair <code>(it, func)<\/code>.\u00a0 <code>it<\/code> is the successor of the sentinel and <code>func<\/code> the function object applied to the range. Thanks to the structured binding, I can directly define the variables <code>sum <\/code>and <code>sum2 <\/code>and display their values (lines 8 and 9).<code> std::ranges::for_each<\/code> uses the sentinel <code>NegativeNumber<\/code>. Consequently, <code>sum2<\/code> has the sum up to the sentinel. The call <code>std::ranges::transform<\/code> (line 10) transforms each element to its square:<code> [](auto num){ return num * num}<\/code>. The transformation stops with the sentinel <code>NegativeNumber.<\/code> Line 11 and line 12 display the transformed values.<\/div>\n<div>Finally, here is the output of the program.<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6365\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sentinel.png\" alt=\"sentinel\" width=\"341\" height=\"402\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sentinel.png 341w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sentinel-254x300.png 254w\" sizes=\"auto, (max-width: 341px) 100vw, 341px\" \/><\/div>\n<\/div>\n<p>You may ask yourself, should I use a classical algorithm of the STL or the ranges pendant on a container? Let me answer this question by comparing both.<\/p>\n<h2><code>std<\/code> Algorithms versus <code>std::ranges<\/code> Algorithms<\/h2>\n<p>Before I dive into the details in my comparison, I want to provide the big picture:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6366\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison.jpg\" alt=\"AlgorithmsComparison\" width=\"600\" height=\"228\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison.jpg 2136w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison-300x114.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison-1024x390.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison-768x292.jpg 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison-1536x585.jpg 1536w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/AlgorithmsComparison-2048x780.jpg 2048w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h3>Range does not support numeric<\/h3>\n<p>The ranges does support the functions of the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/functional\"><code>functional<\/code><\/a>, and the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/algorithm\"><code>algorithm <\/code><\/a>header, but the function of the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/numeric\"><code>numeric<\/code> <\/a>header.\u00a0 <code>The\u00a0<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/numeric\"><code>numeric<\/code> <\/a>header includes <\/code>mathematical functions such as\u00a0 <code>std::gcd, std::midpoint, std::iota,<\/code> or <code>std::accumulate.<\/code><\/p>\n<p>Let me write about more interesting differences.<\/p>\n<h3>Concept support<\/h3>\n<p>The <code>std::ranges<\/code> algorithms are the poster child for concepts.<\/p>\n<div>\n<div>Let&#8217;s start with a comparison of the classical <code>std::sort<\/code> and the new<code> std::ranges::sort<\/code>. <code>std::sort<\/code> and <code>std::ranges::sort<\/code> require a random-access iterator that can access each range element in constant time. Here are the two relevant overloads for <code>std::sort<\/code> and <code>std::ranges::sort<\/code>.<\/div>\n<div><\/div>\n<ul>\n<li><code>std::sort<\/code><\/li>\n<\/ul>\n<p><!-- HTML generated using hilite.me --><\/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;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">RandomIt<\/span> <span style=\"color: #555555;\">&gt;<\/span>\nconstexpr <span style=\"color: #007788; font-weight: bold;\">void<\/span> sort( RandomIt first, RandomIt last );\n<\/pre>\n<\/div>\n<ul>\n<li><code>std:ranges::sort<\/code><\/li>\n<\/ul>\n<p><!-- HTML generated using hilite.me --><\/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;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>random_access_iterator I, std<span style=\"color: #555555;\">::<\/span>sentinel_for<span style=\"color: #555555;\">&lt;<\/span>I<span style=\"color: #555555;\">&gt;<\/span> S,\n         <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Comp<\/span> <span style=\"color: #555555;\">=<\/span> ranges<span style=\"color: #555555;\">::<\/span>less, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Proj<\/span> <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>identity<span style=\"color: #555555;\">&gt;<\/span>\nrequires std<span style=\"color: #555555;\">::<\/span>sortable<span style=\"color: #555555;\">&lt;<\/span>I, Comp, Proj<span style=\"color: #555555;\">&gt;<\/span>\nconstexpr I sort(I first, S last, Comp comp <span style=\"color: #555555;\">=<\/span> {}, Proj proj <span style=\"color: #555555;\">=<\/span> {});\n<\/pre>\n<\/div>\n<div><\/div>\n<div>\n<div>\n<div>What happens when you invoke <code>std::sort<\/code> or <code>std::ranges::sort<\/code> with a container such as<code> std::list<\/code> only supporting a bidirectional iterator?<\/div>\n<h4><code>std::sort<\/code><\/h4>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ sortVector.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;list&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>list<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myList{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">20<\/span>, <span style=\"color: #ff6600;\">0<\/span>};\n   std<span style=\"color: #555555;\">::<\/span>sort(myList.begin(), myList.end());\n    \n}\n<\/pre>\n<\/div>\n<div>\n<div>\n<div>Compiling the program <code>sortVector.cpp<\/code> with the GCC causes an epic error message of 1090 lines.<\/div>\n<div><\/div>\n<div>\u00a0<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6367\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortVector.png\" alt=\"sortVector\" width=\"650\" height=\"361\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortVector.png 1960w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortVector-300x167.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortVector-1024x569.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortVector-768x427.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortVector-1536x854.png 1536w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/div>\n<h4><code>std::ranges::sort<\/code><\/h4>\n<p><!-- HTML generated using hilite.me --><\/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;\">\/\/ sortRangesVector.cpp<\/span>\n\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\n<span style=\"color: #009999;\">#include &lt;list&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>list<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myList{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">20<\/span>, <span style=\"color: #ff6600;\">0<\/span>};\n   std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>sort(myList.begin(), myList.end());\n    \n}\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div>\n<p>Using<code> std::ranges::sort<\/code> instead of<code> std::sort reduces<\/code> the error message drastically. Now, I get 57 error lines.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6368\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorError.png\" alt=\"sortRangesVectorError\" width=\"650\" height=\"148\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorError.png 880w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorError-300x69.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorError-768x175.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<\/div>\n<div>Honestly, the error message of GCC should be easier to read, but I don&#8217;t blame them. We are still in the early process of supporting concepts. Here are the first 10 lines of the 57 lines. I marked the critical message in red.<\/div>\n<div><\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6369\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorErrorLines.png\" alt=\"sortRangesVectorErrorLines\" width=\"650\" height=\"193\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorErrorLines.png 1431w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorErrorLines-300x89.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorErrorLines-1024x303.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/05\/sortRangesVectorErrorLines-768x228.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/div>\n<h2>Which mentoring program should I implement next?<\/h2>\n<p>I&#8217;m happy that the current mentoring program, &#8220;Fundamentals for C++ Professionals&#8221;, is a big success and has more than 35 participants. Now, I will implement an additional mentoring program. All of them are based on my C++ books, posts, and classes.<\/p>\n<p>Make your choice here: <a href=\"https:\/\/www.modernescpp.com\/index.php\/my-next-mentoring-program\">https:\/\/www.modernescpp.com\/index.php\/my-next-mentoring-program<\/a><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>I&#8217;m not done with my comparison of\u00a0 <code>std<\/code> and <code>std::ranges<\/code> algorithms. In my next post, I will write about the unified lookup rules that <code>std::ranges<\/code> algorithms provide and additional safety guarantees.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The ranges library in C++20 supports sentinels. Sentinels stand for the end of a range and can be regarded as generalized end iterators.<\/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":[415,413],"class_list":["post-6370","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-concepts","tag-ranges"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6370","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=6370"}],"version-history":[{"count":2,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6370\/revisions"}],"predecessor-version":[{"id":8394,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6370\/revisions\/8394"}],"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=6370"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6370"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6370"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}