{"id":5524,"date":"2018-10-04T06:03:11","date_gmt":"2018-10-04T06:03:11","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-the-usage-of-concepts-2\/"},"modified":"2023-06-26T11:44:04","modified_gmt":"2023-06-26T11:44:04","slug":"c-core-guidelines-rules-for-the-usage-of-concepts-2","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-the-usage-of-concepts-2\/","title":{"rendered":"C++ Core Guidelines: Rules for the Usage of Concepts"},"content":{"rendered":"<p>We will get concepts with high probability&nbsp;in C++20. Here&nbsp;are the rules from the C++ core guidelines to use them.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5522\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/dice-3613500_1280.png\" alt=\"dice 3613500 1280\" width=\"400\" height=\"444\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/dice-3613500_1280.png 1154w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/dice-3613500_1280-270x300.png 270w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/dice-3613500_1280-923x1024.png 923w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/dice-3613500_1280-768x852.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>First, let me go one&nbsp;step back. What are concepts?<\/p>\n<ul>\n<li><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\"><strong>Concepts<\/strong> are a compile-time predicate. This means concepts can be evaluated at compile-time and return a boolean.&nbsp;<\/span><\/li>\n<\/ul>\n<p>The following questions are. What are the pros of concepts in C++?&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Concepts<\/strong><\/p>\n<ul>\n<li>Empower programmers to express their requirements as part of the interface directly.<\/li>\n<li>Support the overloading of functions and the specialization of class templates based on the requirements of the template parameters.<\/li>\n<li>Produce drastically improved error messages by comparing the requirements of the template parameter with the applied template arguments.<\/li>\n<li>It can be used as placeholders for generic programming.<\/li>\n<li>Empower you to define your concepts.<\/li>\n<\/ul>\n<p>Now, one step forward. Here are the four rules for today:<\/p>\n<ul style=\"margin-top: 0px; margin-bottom: 1rem; color: #515151; font-family: 'PT Sans', Helvetica, Arial, sans-serif; font-size: 20px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-concepts\" style=\"color: #268bd2; text-decoration: none;\">T.10: Specify concepts for all template arguments<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-std-concepts\" style=\"color: #268bd2; text-decoration: none;\">T.11: Whenever possible, use standard concepts<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-auto\" style=\"color: #268bd2; text-decoration: none;\">T.12: Prefer concept names over&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">auto<\/code>&nbsp;for local variables<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-shorthand\" style=\"color: #268bd2; text-decoration: none;\">T.13: Prefer the shorthand notation for simple, single-type argument concepts<\/a><\/li>\n<\/ul>\n<p>Let&#8217;s start with the first rule.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-concepts\" style=\"color: #268bd2; text-decoration: none;\">T.10: Specify concepts for all template arguments<\/a><\/h2>\n<p>There is not much to add to this rule. Because of correctness and readability, you should use concepts for all template parameters. You can do it in a verbose way.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nrequires Integral&lt;T&gt;()\r\nT gcd(T a, T b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Or you can do it more concisely.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;Integral T&gt;\r\nT gcd(T a, T b){\r\n  <span style=\"color: #0000ff;\">if<\/span>( b == 0 ){ <span style=\"color: #0000ff;\">return<\/span> a; }\r\n  <span style=\"color: #0000ff;\">else<\/span>{\r\n    <span style=\"color: #0000ff;\">return<\/span> gcd(b, a % b);\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In the first example,&nbsp; I specify the concept in the required clause, but I can use the concept <code>Integral<\/code> just in place of the keyword typename or class. The concept <code>Integral<\/code> has to be a&nbsp; constant expression that returns a boolean.&nbsp;<\/p>\n<p>I created the concept by using <code><span style=\"font-family: 'courier new', courier;\">std::is_integral<\/span><\/code> from the type traits library.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nconcept <span style=\"color: #2b91af;\">bool<\/span> Integral(){\r\n  <span style=\"color: #0000ff;\">return<\/span> std::is_integral&lt;T&gt;::value;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Defining your concepts, as I did, is not the best idea.<\/p>\n<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-std-concepts\" style=\"color: #268bd2; text-decoration: none;\">T.11: Whenever possible, use standard concepts<\/a><\/h2>\n<p>Okay, if possible, you should use the concepts from the Guidelines Support Library (GSL) or the Ranges TS. Let&#8217;s see what we have. I ignore the concepts of the GSL because they are mainly part of the Ranges TS. Here are the concepts of the Range TS from the document <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2016\/n4569.pdf\">N4569<\/a>: Working Draft, C++ Extension for Ranges.<\/p>\n<h3>Core language concepts<\/h3>\n<ul>\n<li><code>Same<\/code><\/li>\n<li><code>DerivedFrom<\/code><\/li>\n<li><code>ConvertibleTo<\/code><\/li>\n<li><code>Common<\/code><\/li>\n<li><code>Integral<\/code><\/li>\n<li><code>Signed Integral<\/code><\/li>\n<li><code>Unsigned Integral<\/code><\/li>\n<li><code>Assignable<\/code><\/li>\n<li><code>Swappable<\/code><\/li>\n<\/ul>\n<h3>Comparison concepts<\/h3>\n<ul>\n<li><code>Boolean<\/code><\/li>\n<li><code>EqualityComparable<\/code><\/li>\n<li><code>StrictTotallyOrdered<\/code><\/li>\n<\/ul>\n<h3 style=\"color: #000000;\">Object concepts<\/h3>\n<ul>\n<li><code>Destructible<\/code><\/li>\n<li><code>Constructible<\/code><\/li>\n<li><code>DefaultConstructible<\/code><\/li>\n<li><code>MoveConstructible<\/code><\/li>\n<li><code>Copy Constructible<\/code><\/li>\n<li><code>Movable<\/code><\/li>\n<li><code>Copyable<\/code><\/li>\n<li><code>Semiregular<\/code><\/li>\n<li><code>Regular<\/code><\/li>\n<\/ul>\n<h3>Callable concepts<\/h3>\n<ul>\n<li><code>Callable<\/code><\/li>\n<li><code>RegularCallable<\/code><\/li>\n<li><code>Predicate<\/code><\/li>\n<li><code>Relation<\/code><\/li>\n<li><code>StrictWeakOrder<\/code><\/li>\n<\/ul>\n<p>If you want to know what each of these concepts means, the already mentioned document <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2016\/n4569.pdf\">N4569<\/a> gives you the answers. The concept definitions are based on the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type traits library<\/a>. Here are for example, the definitions of the concepts <code>Integral, Signed Integral<\/code>, and<code> Unsigned Integral<\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Integral() {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> SignedIntegral() {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>() <span style=\"color: #555555;\">&amp;&amp;<\/span> is_signed<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> UnsignedIntegral() {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>() <span style=\"color: #555555;\">&amp;&amp;<\/span> <span style=\"color: #555555;\">!<\/span>SignedIntegral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>();\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The functions <code>std::is_integral&lt;T&gt;<\/code> and <code>std::is_signed&lt;T&gt;<\/code>&nbsp;are predicates from the type traits library.<\/p>\n<p>Additionally, the names are used in the&nbsp;<span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">text of the C++ standard to define the expectations of the standard library. They are concepts that are not enforced but document the requirement for an algorithm, such as <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/sort\"><code>std::sort<\/code><\/a>.&nbsp;<\/span><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #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>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort( RandomIt first, RandomIt last );\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The first overload of <code>std::sort<\/code> requires two <strong>RandomAccessIterator<\/strong>. Now, I have to say what a <strong>RandomAccessIterator<\/strong> is:<\/p>\n<ul>\n<li><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">A&nbsp;<\/span><strong class=\"selflink\" style=\"font-weight: bold; color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif;\">RandomAccessIterator<\/span><\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;is a&nbsp;<\/span><strong>BidirectionalIterator<\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;that can be moved to point to any element in constant time.<\/span><\/li>\n<li><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">A&nbsp;<\/span><strong class=\"selflink\" style=\"font-weight: bold; color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif;\">BidirectionalIterator<\/span><\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;is a&nbsp;<\/span><strong><span style=\"font-family: Georgia, 'DejaVu Serif', serif;\">ForwardIterator<\/span><\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\"><strong>&nbsp;<\/strong>that can be moved in both directions&nbsp;<\/span><\/li>\n<li><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">A&nbsp;<\/span><strong class=\"selflink\" style=\"font-weight: bold; color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif;\">ForwardIterator<\/span><\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;is an&nbsp;<\/span><strong><span style=\"font-family: Georgia, 'DejaVu Serif', serif;\">Iterator<\/span><\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;that can read data from the pointed-to element.<\/span><\/li>\n<li><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">The&nbsp;<\/span><strong class=\"selflink\" style=\"font-weight: bold; color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\"><span style=\"font-family: Georgia, 'DejaVu Serif', serif;\">Iterator<\/span><\/strong><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;requirements describe types that can be used to identify and traverse the elements of a container.<\/span><\/li>\n<\/ul>\n<p><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">For the details to the named requirements used in the text of the C++ standard, read<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\"> cppreference.com<\/a>.&nbsp;<\/span><\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-auto\" style=\"color: #268bd2; text-decoration: none;\">T.12: Prefer concept names over&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">auto<\/code>&nbsp;for local variables<\/a><\/h2>\n<p><code>auto<\/code> is an unconstrained concept (placeholder), but you should use constrained concepts.&nbsp;<span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">You can use constrained concepts in each situation, where you can use unconstrained placeholders (<\/span><span style=\"color: #444444; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; font-family: 'courier new', courier;\">auto<\/span><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">).&nbsp;<\/span>If this is not an intuitive rule?<\/p>\n<p>Here is an example to make my point.&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: #0099ff; font-style: italic;\">\/\/ constrainedUnconstrainedConcepts.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;type_traits&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&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> T<span style=\"color: #555555;\">&gt;<\/span>                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\nconcept <span style=\"color: #007788; font-weight: bold;\">bool<\/span> Integral(){                \r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> getIntegral(<span style=\"color: #007788; font-weight: bold;\">int<\/span> val){\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> val <span style=\"color: #555555;\">*<\/span> <span style=\"color: #ff6600;\">5<\/span>;\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> std<span style=\"color: #555555;\">::<\/span>boolalpha <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\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;\">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>};\r\n  <span style=\"color: #006699; font-weight: bold;\">for<\/span> (Integral<span style=\"color: #555555;\">&amp;<\/span> i<span style=\"color: #555555;\">:<\/span> myVec) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  \r\n\r\n  Integral b<span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">true<\/span>;                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> b <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  Integral integ<span style=\"color: #555555;\">=<\/span> getIntegral(<span style=\"color: #ff6600;\">10<\/span>);                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> integ <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> integ1<span style=\"color: #555555;\">=<\/span> getIntegral(<span style=\"color: #ff6600;\">10<\/span>);                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> integ1 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"margin: 0px 0px 10px; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">I defined the concept&nbsp;<code><span>Integral&nbsp;<\/span><\/code>in line (1). Hence I iterate over integrals in the range-based for-loop in line (2), and the variables<span>&nbsp;<code>b<\/code><\/span>&nbsp;and <code>integ<\/code> inline (3) and (4) have to be integrals. &nbsp;I&#8217;m not so strict in line (5). Here I&#8217;m okay with an unconstrained concept.<\/p>\n<p style=\"margin: 0px 0px 10px; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">In the end, the output of the program.&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5523\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/constrainedUnconstrainedConcepts.png\" alt=\"constrainedUnconstrainedConcepts\" width=\"700\" height=\"174\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/constrainedUnconstrainedConcepts.png 1557w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/constrainedUnconstrainedConcepts-300x75.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/constrainedUnconstrainedConcepts-1024x255.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/constrainedUnconstrainedConcepts-768x191.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/constrainedUnconstrainedConcepts-1536x382.png 1536w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-shorthand\" style=\"color: #268bd2; text-decoration: none;\">T.13: Prefer the shorthand notation for simple, single-type argument concepts<\/a><\/h2>\n<p>The example from the C++ Core Guidelines looks quite innocent but has the potential to revolutionize the way we write templates. Here it is.<\/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>       <span style=\"color: #0099ff; font-style: italic;\">\/\/ Correct but verbose: \"The parameter is<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">\/\/    requires Sortable&lt;T&gt;   \/\/ of type T which is the name of a type<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort(T<span style=\"color: #555555;\">&amp;<\/span>);             <span style=\"color: #0099ff; font-style: italic;\">\/\/ that is Sortable\"<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Sortable T<span style=\"color: #555555;\">&gt;<\/span>       <span style=\"color: #0099ff; font-style: italic;\">\/\/ Better (assuming support for concepts): \"The parameter is of type T<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort(T<span style=\"color: #555555;\">&amp;<\/span>);             <span style=\"color: #0099ff; font-style: italic;\">\/\/ which is Sortable\"<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">sort<\/span>(Sortable<span style=\"color: #555555;\">&amp;<\/span>);      <span style=\"color: #0099ff; font-style: italic;\">\/\/ Best (assuming support for concepts): \"The parameter is Sortable\"<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>This example shows three variations to declare the function template <code>sort<\/code>. All variations are semantically equivalent and require that the template parameter supports the concept <code>Sortable<\/code>. The last variation looks like a function declaration but is a function template declaration because the parameter is a concept, not a concrete type. To say it once more:<strong style=\"font-weight: bold; color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">&nbsp;<code>sort<\/code> becomes due to the concept parameter of a function template.<\/strong>&nbsp;<span style=\"font-family: 'courier new', courier;\"><\/span><span style=\"color: #444444; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;&nbsp;<\/span><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>The C++ core guidelines say: &#8220;Defining good concepts is non-trivial. Concepts are meant to represent fundamental concepts in an application domain.&#8221;&nbsp; Let&#8217;s see what that means in my <a href=\"https:\/\/goo.gl\/quajuA\">next post<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We will get concepts with high probability&nbsp;in C++20. Here&nbsp;are the rules from the C++ core guidelines to use them.<\/p>\n","protected":false},"author":21,"featured_media":5522,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[415],"class_list":["post-5524","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5524","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=5524"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5524\/revisions"}],"predecessor-version":[{"id":6811,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5524\/revisions\/6811"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5522"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5524"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5524"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5524"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}