{"id":6328,"date":"2022-03-21T10:51:48","date_gmt":"2022-03-21T10:51:48","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/softwaredesign-with-traits-and-tag-dispatching\/"},"modified":"2023-06-26T09:10:26","modified_gmt":"2023-06-26T09:10:26","slug":"softwaredesign-with-traits-and-tag-dispatching","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/softwaredesign-with-traits-and-tag-dispatching\/","title":{"rendered":"Software Design with Traits and Tag Dispatching"},"content":{"rendered":"<p>Tag Dispatching enables it to choose a function based on the type characteristics. This decision takes place at compile time and is based on traits.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6320\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/PolicyAndTraits.png\" alt=\"PolicyAndTraits\" width=\"650\" height=\"398\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/PolicyAndTraits.png 907w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/PolicyAndTraits-300x184.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/PolicyAndTraits-768x470.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Tag dispatching is based on traits. Consequentially, I want to write a few words about traits.<\/p>\n<h2>Traits<\/h2>\n<p>Traits are class templates that provide characteristics of a generic type. They can extract one or more characteristics of a class template.<\/p>\n<p>You may already assume it; the metafunctions from the<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\"> type-traits<\/a> library are typical examples of traits in C++. I have already written a few posts about them. Here are they:<\/p>\n<ol>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-type-checks\">Type Checks<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-type-comparisons\">Type Comparisons<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-std-is-base-of\"><code>std::is_base_of<\/code><\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library\">Correctness<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-performance\">Performance<\/a><\/li>\n<\/ol>\n<p>&nbsp;Before I directly jump in this post in tag dispatching, I want to introduce the<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/iterator\/iterator_traits\"> iterator traits<\/a>. The following code snippet shows their partial specialization for pointers:<\/p>\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>T<span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> iterator_traits<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">*&gt;<\/span> { \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> difference_type <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">ptrdiff_t<\/span>; \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> value_type <span style=\"color: #555555;\">=<\/span> T; \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> pointer <span style=\"color: #555555;\">=<\/span> T<span style=\"color: #555555;\">*<\/span>; \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> reference <span style=\"color: #555555;\">=<\/span> T<span style=\"color: #555555;\">&amp;<\/span>; \r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> iterator_category <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>random_access_iterator_tag; \r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The iterator categories build the following hierarchy:<\/p>\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;\">struct<\/span> input_iterator_tag{}; \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> output_iterator_tag{}; \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> forward_iterator_tag<span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> input_iterator_tag{}; \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> bidirectional_iterator_tag<span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> forward_iterator_tag{}; \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> random_access_iterator_tag<span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> bidirectional_iterator_tag{}; \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;The various iterator categories correspond to the container of the Standard Template Library.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5526\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories.png\" alt=\"IteratorCategories\" width=\"550\" height=\"332\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories.png 990w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories-300x181.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories-768x464.png 768w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/p>\n<p>The following relation holds for the iterator categories and their support operations. A random-access iterator is a bidirectional iterator, and a bidirectional iterator is a forward iterator. This means <code>std::array, std::vector,<\/code> and <code>std::string<\/code> support a random-access iterator but not <code>std::list<\/code>.<\/p>\n<\/p>\n<h2>Tag Dispatching<\/h2>\n<p>Now, I can apply tag dispatching and implement a fine-tailored <code>advance_<\/code> algorithm optimized for the used container. First of all, <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/iterator\/advance\"><code>std::advance<\/code><\/a> is already part of the standard template library:<\/p>\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;\">InputIt<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Distance<\/span> <span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance( InputIt<span style=\"color: #555555;\">&amp;<\/span> it, Distance n );            (until C<span style=\"color: #555555;\">++<\/span><span style=\"color: #ff6600;\">17<\/span>)\r\n<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;\">InputIt<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Distance<\/span> <span style=\"color: #555555;\">&gt;<\/span>\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">void<\/span> advance( InputIt<span style=\"color: #555555;\">&amp;<\/span> it, Distance n );  (since C<span style=\"color: #555555;\">++<\/span><span style=\"color: #ff6600;\">17<\/span>)\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><code>std::advance<\/code> increments a given iterator <code>it<\/code> by<code> n<\/code> elements. If n is negative, the iterator is decremented. Consequentially, the container providing the iterator must be, in this case, bidirectional.<\/p>\n<p>Here is my implementation of <code>advance_<\/code>:<\/p>\n<p>&nbsp;<\/p>\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;\">\/\/ advance_.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iterator&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;forward_list&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;list&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> InputIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>                    \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_impl(InputIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n, std<span style=\"color: #555555;\">::<\/span>input_iterator_tag) {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"InputIterator used\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>; \r\n    <span style=\"color: #006699; font-weight: bold;\"><\/span>if (n &gt;= 0) { while (n--) ++it; }\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> BidirectionalIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>            <span style=\"color: #0099ff; font-style: italic;\">  <\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_impl(BidirectionalIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n, std<span style=\"color: #555555;\">::<\/span>bidirectional_iterator_tag) {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"BidirectionalIterator used\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (n <span style=\"color: #555555;\">&gt;=<\/span> <span style=\"color: #ff6600;\">0<\/span>) \r\n        <span style=\"color: #006699; font-weight: bold;\">while<\/span> (n<span style=\"color: #555555;\">--<\/span>) <span style=\"color: #555555;\">++<\/span>i;\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> \r\n        <span style=\"color: #006699; font-weight: bold;\">while<\/span> (n<span style=\"color: #555555;\">++<\/span>) <span style=\"color: #555555;\">--<\/span>i;\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> RandomAccessIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>             \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_impl(RandomAccessIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n, std<span style=\"color: #555555;\">::<\/span>random_access_iterator_tag) {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"RandomAccessIterator used\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    i <span style=\"color: #555555;\">+=<\/span> n;                                                             \/\/ (5)\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> InputIterator, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Distance<span style=\"color: #555555;\">&gt;<\/span>                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance_(InputIterator<span style=\"color: #555555;\">&amp;<\/span> i, Distance n) {\r\n    <span style=\"color: #006699; font-weight: bold;\">typename<\/span> std<span style=\"color: #555555;\">::<\/span>iterator_traits<span style=\"color: #555555;\">&lt;<\/span>InputIterator<span style=\"color: #555555;\">&gt;::<\/span>iterator_category category;    \r\n    advance_impl(i, n, category);                                               \r\n}\r\n  \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\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;\">0<\/span>, <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>};               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myVecIt <span style=\"color: #555555;\">=<\/span> myVec.begin();                                               \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myVecIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myVecIt <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    advance_(myVecIt, <span style=\"color: #ff6600;\">5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myVecIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myVecIt <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\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;\">0<\/span>, <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>};                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myListIt <span style=\"color: #555555;\">=<\/span> myList.begin();                                             \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myListIt <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    advance_(myListIt, <span style=\"color: #ff6600;\">5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myListIt <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\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> myForwardList{<span style=\"color: #ff6600;\">0<\/span>, <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>}; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myForwardListIt <span style=\"color: #555555;\">=<\/span> myForwardList.begin();                               \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myForwardListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myForwardListIt <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    advance_(myForwardListIt, <span style=\"color: #ff6600;\">5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*myForwardListIt: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>myForwardListIt <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I use in the example a <code>std::vector<\/code> (line 1), a <code>std::list<\/code> (line 2), and a<code> std::forward_list<\/code> (line 3). A <code>std::vector<\/code> supports a random-access iterator, a <code>std::list<\/code> bidirectional iterator, and a <code>std::forward_list<\/code> forward iterator. The call <code> std<span style=\"color: #555555;\">::<\/span>iterator_traits<span style=\"color: #555555;\">&lt;<\/span>InputIterator<span style=\"color: #555555;\">&gt;::<\/span>iterator_category category<\/code>; in the function <code>advance_&nbsp; <\/code>(line 4) determines the supported iterator category based on the given iterator. The final call <code>advance_impl(i, n, category) <\/code>finally dispatches to the most specialized overload of the implementation function<code> advance_impl.<\/code><\/p>\n<p>To visualize the dispatch, I added a short message to implementation functions <code>advance_imp<\/code>l.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6327\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/advance_.png\" alt=\"advance \" width=\"300\" height=\"316\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/advance_.png 401w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/03\/advance_-284x300.png 284w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>What are the advantages of such a fine-tuned advance implementation?<\/p>\n<ol>\n<li><strong>Type safety<\/strong>: The compiler decides which version of <code>advance_impl<\/code> is used. Consequentially, you cannot invoke an implementation requiring a bidirectional iterator with a forward iterator. Backward iterating with a forward iterator is undefined behavior.<\/li>\n<li><strong>Performance<\/strong>: Putting a forward or bidirectional iterator n position further requires n increment operation. Its complexity is, therefore, linear. This observation does not hold for a random access iterator: Pointer arithmetic such as<code> i <span style=\"color: #555555;\">+=<\/span> n<\/code> (line 5) is a constant operation.<\/li>\n<\/ol>\n<h2>What&#8217;s next?<\/h2>\n<p>In my next post, I bridge dynamic polymorphism (object orientation) with static polymorphism (templates) to introduce a sophisticated technique: type erasure.<\/p>\n<h2>The Future of Modernes C++<\/h2>\n<p>The type erasure post will be my last post about templates for now. To get the previous ones, use the <a href=\"https:\/\/www.modernescpp.com\/index.php\/der-einstieg-in-modernes-c#h9-templates\">TOC <\/a>or the category&nbsp;<a href=\"https:\/\/www.modernescpp.com\/index.php\/category\/templates\">Templates<\/a>. Afterward, I will continue to write about C++20 and will peek into the C++23 future. If you have some exciting post ideas, please write me an e-mail: <a href=\"mailto:Rainer.Grimm@modernescpp.de\">Rainer.Grimm@modernescpp.de<\/a>.<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tag Dispatching enables it to choose a function based on the type characteristics. This decision takes place at compile time and is based on traits.<\/p>\n","protected":false},"author":21,"featured_media":6320,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[422,423],"class_list":["post-6328","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates","tag-tag-dispatching","tag-traits"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6328","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=6328"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6328\/revisions"}],"predecessor-version":[{"id":6676,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6328\/revisions\/6676"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6320"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6328"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6328"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6328"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}