{"id":5496,"date":"2018-08-31T08:33:41","date_gmt":"2018-08-31T08:33:41","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-templates-and-generic-programming\/"},"modified":"2018-08-31T08:33:41","modified_gmt":"2018-08-31T08:33:41","slug":"c-core-guidelines-rules-for-templates-and-generic-programming","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-templates-and-generic-programming\/","title":{"rendered":"C++ Core Guidelines: Rules for Templates and Generic Programming"},"content":{"rendered":"<p>I this post I give an introduction to the rules for generic programming in C++. Generic programming is, from my point of view, the outstanding feature and the future of C++. Hence it follows that this and the upcoming posts are about the future of C++.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5494\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/future.jpg\" alt=\"future\" width=\"500\" height=\"333\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/future.jpg 1920w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/future-300x200.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/future-1024x683.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/future-768x512.jpg 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/future-1536x1024.jpg 1536w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>First, I use the terms templates and generic programming, whatever fits best. Of course, I know that templates are just a way to write generic code. I assume you know what templates in C++ are, but you don&#8217;t know what generic programming means. Here is my favorite definition from <a href=\"https:\/\/en.wikipedia.org\/wiki\/Generic_programming\">Wikipedia.<\/a><\/p>\n<ul>\n<li><b>Generic programming<\/b> is a style of computer programming in which algorithms are written in terms of types <i>to-be-specified-later<\/i> that are then <i>instantiated<\/i> when needed for specific types provided as parameters.<\/li>\n<\/ul>\n<p>The rules to templates are about the current C++17 and the upcoming C++20 standard. Of course, I assume that we will get concepts with C++20. In sum, there are 100 rules to concepts, template interfaces, template definitions, template hierarchies, variadic templates, and template metaprogramming. The first five rules are pretty general.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-raise\">T.1: Use templates to raise the level of abstraction of code<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-algo\">T.2: Use templates to express algorithms that apply to many argument types<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-cont\">T.3: Use templates to express containers and ranges<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-generic-oo\">T.5: Combine generic and OO techniques to amplify their strengths, not their costs<\/a><\/li>\n<\/ul>\n<p>In the examples, concepts are often commented on. If you want to try them out, comment them in and use at least a&nbsp; GCC 6.1 compiler with the flag&nbsp;<code>-fconcepts<\/code> or an online compiler: <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/constraints\">constraints and concepts.<\/a><\/p>\n<p>Concepts are predicates on templates that are evaluated at compile time. They should model semantic categories such as&nbsp;<code>Number,&nbsp;<\/code><code>Callable, Iterator<\/code> or <code>Range<\/code> but not syntactic restrictions such as <code>HasPlus,<\/code> or <code>IsInvocable. <\/code>Here are more details of <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/concepts\">concepts.<\/a><\/p>\n<p>Maybe, you are puzzled by the difference between semantic categories and syntactic restrictions. The first rule helps to distinguish both terms.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-raise\">T.1: Use templates to raise the level of abstraction of code<\/a><\/h2>\n<p>Here is the example from the guidelines, but I called the second concept <code>Addable. <\/code><\/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;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ requires Incrementable&lt;T&gt;<\/span>\r\nT sum1(vector<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;&amp;<\/span> v, T s)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> x <span style=\"color: #555555;\">:<\/span> v) s <span style=\"color: #555555;\">+=<\/span> x;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\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> T<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ requires Addable&lt;T&gt;<\/span>\r\nT sum2(vector<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;&amp;<\/span> v, T s)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> x <span style=\"color: #555555;\">:<\/span> v) s <span style=\"color: #555555;\">=<\/span> s <span style=\"color: #555555;\">+<\/span> x;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>What is wrong with both concepts? Both concepts are too specific. Both concepts are based on specific operations, such as the increment and the + operation. Let&#8217;s go one step further from the syntactic constraints to the semantic category <code>Arithmetic.<\/code><\/p>\n<p>&nbsp;<\/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;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ requires Arithmetic&lt;T&gt;<\/span>\r\nT sum(const vector<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;&amp;<\/span> v, T s)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> x <span style=\"color: #555555;\">:<\/span> v) s <span style=\"color: #555555;\">+=<\/span> x;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the algorithm has minimal requirements. Hold: the algorithm is better but not good. It only works on a <code>std::vector<\/code>. It&#8217;s generic on the type of the container but not on the container. Let me generalize the sum algorithm once more.<\/p>\n<p>&nbsp;<\/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;\">typename<\/span> Cont, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ requires Container&lt;Cont&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ &amp;&amp; Arithmetic&lt;T&gt;<\/span>\r\nT sum(const Cont<span style=\"color: #555555;\">&amp;<\/span> v, T s)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> x <span style=\"color: #555555;\">:<\/span> v) s <span style=\"color: #555555;\">+=<\/span> x;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, it&#8217;s fine. Maybe you prefer a more concise definition of the sum. Instead of the keyword typename, I use the concepts directly.<\/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>Container Cont, Arithmetic T<span style=\"color: #555555;\">&gt;<\/span>\r\nT sum(const Cont<span style=\"color: #555555;\">&amp;<\/span> cont, T s){\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> x <span style=\"color: #555555;\">:<\/span> cont) s <span style=\"color: #555555;\">+=<\/span> x;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-algo\">T.2: Use templates to express algorithms that apply to many argument types<\/a><\/h2>\n<p>When you study the first overload of <code>std::find<\/code> at <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/find\">cppreference.com,<\/a> it looks like this:<\/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;\">T<\/span> <span style=\"color: #555555;\">&gt;<\/span>\r\nInputIt find( InputIt first, InputIt last, <span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&amp;<\/span> value );\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The types of Iterators are encoded in their names: <code>InputIt<\/code> stands for input iterator and means that the iterator can read from the pointed-to element. There are two issues with this declaration:<\/p>\n<ol>\n<li>The requirements for the iterators are encoded in the name. This reminds me of the infamous <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hungarian_notation\">Hungarian notation<\/a>.&nbsp;<\/li>\n<li>No requirement stated that the pointed-to element can be compared with the value.<\/li>\n<\/ol>\n<p>Let me use the iterator concept directly:<\/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>Input_iterator Iter, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Val<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ Equality_comparable&lt;Value_type&lt;Iter&gt;, Val&gt;<\/span>\r\nIter find(Iter b, Iter e, Val v)\r\n{\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-cont\">T.3: Use templates to express containers and ranges<\/a><\/h2>\n<p>Okay. It&#8217;s pretty obvious to make a container generic. For example, here is a&nbsp;<code>Vector.<\/code><\/p>\n<p>&nbsp;<\/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;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ requires Regular&lt;T&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Vector<\/span> {\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n    T<span style=\"color: #555555;\">*<\/span> elem;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ points to sz Ts<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> sz;\r\n};\r\n\r\nVector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> v(<span style=\"color: #ff6600;\">10<\/span>);\r\nv[<span style=\"color: #ff6600;\">7<\/span>] <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">9.9<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Okay, fine, but when is a user-defined type <code>T<\/code> regular? The document Fundamentals of Generic Programming defines a type T regular if it behaves like a built-in type such as <code>bool,<\/code> <code>int,<\/code> or <code>double.<\/code> I should mention it. The paper Fundamentals of Generic Programming is from James C. Dehnert and Alexander Stepanow. I assume you already know Alexander Stephanow by name. He is the well-known father of the Standard Template Library.<\/p>\n<p>The document states that a type T is called regular if it defines the following operations:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5495\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/regular.png\" alt=\"regular\" width=\"300\" height=\"156\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/regular.png 407w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/08\/regular-300x156.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The equality, inequality, and ordering operation on T could be defined component-wise.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>My original plan was to write about rule 5:&nbsp;<a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-generic-oo\">T.5: Combine generic and OO techniques to amplify their strengths, not their costs.<\/a> I changed my plan because rule 5 is relatively short and mentioned type erasure as a use-case for this technique. Type erasure is a technique to represent various concrete types through a single interface. Type erasure with templates could not be explained in a few sentences; therefore, I will write in my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-type-erasure\">next post<\/a> about this challenging technique.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I this post I give an introduction to the rules for generic programming in C++. Generic programming is, from my point of view, the outstanding feature and the future of C++. Hence it follows that this and the upcoming posts are about the future of C++.<\/p>\n","protected":false},"author":21,"featured_media":5494,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[],"class_list":["post-5496","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5496","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=5496"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5496\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5494"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}