{"id":5817,"date":"2019-11-29T13:24:14","date_gmt":"2019-11-29T13:24:14","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-details\/"},"modified":"2023-06-26T09:57:30","modified_gmt":"2023-06-26T09:57:30","slug":"c-20-concepts-the-details","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-details\/","title":{"rendered":"C++20: Concepts, the Details"},"content":{"rendered":"<p>In my last post, <a href=\"http:\/\/bit.ly\/2s7giyL\">C++20: Two Extremes and the Rescue with Concepts<\/a>, I gave the first motivation for concepts. Concepts put semantic constraints on template parameters. Today, I present different <span>use-cases<\/span> for concepts in a compact form.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5808\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png\" alt=\"TimelineCpp20Concepts\" width=\"650\" height=\"255\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png 954w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-300x118.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-768x301.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<h2>The Details<\/h2>\n<p>Just keep it in mind: What are the advantages of concepts?<\/p>\n<ul>\n<li>Requirements for templates are part of the interface.<\/li>\n<li>The overloading of functions or specialization of class templates can be based on concepts.<\/li>\n<li>We get an improved error message because the compiler compares the requirements of the template parameter with the actual template arguments<\/li>\n<li>You can use predefined concepts or define your own.<\/li>\n<li>The usage of auto and concepts is unified. Instead of auto, you can use a concept.<\/li>\n<li>If a function declaration uses a concept, it automatically becomes a function template. Writing function templates is, therefore, as easy as writing a function.<\/li>\n<\/ul>\n<p>This post is about the first three points. Let me show many different usages of concepts:<\/p>\n<\/p>\n<h3>Three Ways<\/h3>\n<p>There are three ways to use the concept <span style=\"font-family: courier new, courier;\">Sortable<\/span>. For simplicity reasons, I only show the declaration of the function template.<\/p>\n<h4>Requires Clause<\/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: #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: #555555;\">&gt;<\/span>\r\n    requires Sortable<span style=\"color: #555555;\">&lt;<\/span>Cont<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort(Cont<span style=\"color: #555555;\">&amp;<\/span> container);\r\n<\/pre>\n<\/div>\n<h4>Trailing Requires Clause<\/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: #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: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort(Cont<span style=\"color: #555555;\">&amp;<\/span> container) requires Sortable<span style=\"color: #555555;\">&lt;<\/span>Cont<span style=\"color: #555555;\">&gt;<\/span>;\r\n<\/pre>\n<\/div>\n<h4>Constrained Template Parameters<\/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: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Sortable Cont<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> sort(Cont<span style=\"color: #555555;\">&amp;<\/span> container)\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The algorithm <span style=\"font-family: Courier New;\">sort <\/span>requires, in this case, that the container is sortable.<span style=\"font-family: Courier New, Courier, monospace;\"> Sortable <\/span>has to be a constant expression and a predicate.<\/p>\n<h4>Classes<\/h4>\n<p>You can define a class template that only accepts objects.<\/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>Object T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyVector<\/span>{};\r\n\r\nMyVector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> v1;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\nMyVector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;&gt;<\/span> v2;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ ERROR: int&amp; does not satisfy the constraint Object<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The compiler complains that a reference is not an object. Maybe you wonder what an object is.? A possible implementation of the type-traits function <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_object\"><span style=\"font-family: Courier New, Courier, monospace;\">std::is_object<\/span><\/a> answers:<\/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;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_object <span style=\"color: #555555;\">:<\/span> std<span style=\"color: #555555;\">::<\/span>integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>,\r\n                     std<span style=\"color: #555555;\">::<\/span>is_scalar<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">||<\/span>\r\n                     std<span style=\"color: #555555;\">::<\/span>is_array<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value  <span style=\"color: #555555;\">||<\/span>\r\n                     std<span style=\"color: #555555;\">::<\/span>is_union<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value  <span style=\"color: #555555;\">||<\/span>\r\n                     std<span style=\"color: #555555;\">::<\/span>is_class<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value<span style=\"color: #555555;\">&gt;<\/span> {};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>An object is either a scalar, an array, a union, or a class.<\/p>\n<h4>Member Functions<\/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%;\">template<span style=\"color: #555555;\">&lt;<\/span>Object T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyVector<\/span>{\r\n    ... \r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> push_back(<span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&amp;<\/span> e) requires Copyable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>{}\r\n    ...\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In this case, the member function requires the template parameter T to be copyable.<\/p>\n<h4>Variadic Templates<\/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: #009999;\">&nbsp;<span style=\"color: #0099ff; font-style: italic;\">\/\/ allAnyNone.cpp<\/span><br \/><br \/>#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;type_traits&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>\r\nconcept Arithmetic <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_arithmetic<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Arithmetic... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> all(Args... args) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> (... <span style=\"color: #555555;\">&amp;&amp;<\/span> args); }\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Arithmetic... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> any(Args... args) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> (... <span style=\"color: #555555;\">||<\/span> args); }\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Arithmetic... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> none(Args... args) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">!<\/span>(... <span style=\"color: #555555;\">||<\/span> args); }\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>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"all(5, true, 5.5, false): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> all(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #336666;\">false<\/span>) <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> <span style=\"color: #cc3300;\">\"any(5, true, 5.5, false): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> any(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #336666;\">false<\/span>) <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> <span style=\"color: #cc3300;\">\"none(5, true, 5.5, false): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> none(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #336666;\">false<\/span>) <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>You can use concepts in variadic templates.&nbsp; The definition of the function templates is based on <a href=\"https:\/\/www.modernescpp.com\/index.php\/fold-expressions\">fold expressions<\/a>. <span style=\"font-family: Courier New;\">all<\/span>, <span style=\"font-family: Courier New;\">any<\/span>, and <span style=\"font-family: Courier New;\">none <\/span>require from it type parameter <span style=\"font-family: courier new, courier;\">T<\/span> that has to support the concept <span style=\"font-family: Courier New;\">Arithmetic. Arithmetic <\/span>essential means that <span style=\"font-family: Courier New;\">T<\/span> is either integral or floating-point.<\/p>\n<p>The brand-new Microsoft compiler 19.23 partially supports the concepts syntax.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5816\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/allAnyNone.png\" alt=\"allAnyNone\" width=\"300\" height=\"143\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/allAnyNone.png 1088w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/allAnyNone-300x143.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/allAnyNone-1024x488.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/allAnyNone-768x366.png 768w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h4>More Requirements<\/h4>\n<p>Of course, you can use more than one requirement for the template parameters.<\/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>SequenceContainer S,   \r\n          EqualityComparable<span style=\"color: #555555;\">&lt;<\/span>value_type<span style=\"color: #555555;\">&lt;<\/span>S<span style=\"color: #555555;\">&gt;&gt;<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nIterator_type<span style=\"color: #555555;\">&lt;<\/span>S<span style=\"color: #555555;\">&gt;<\/span> find(S<span style=\"color: #555555;\">&amp;&amp;<\/span> seq, <span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&amp;<\/span> val){\r\n    ...\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The function template&nbsp;<span style=\"font-family: courier new, courier;\">find<\/span> requires that the container<span style=\"font-family: courier new, courier;\"> S<\/span> is a <span style=\"font-family: courier new, courier;\">SequenceContainer<\/span> and its elements are <span style=\"font-family: courier new, courier;\">EqualityComparable<\/span>.<\/p>\n<h4>Overloading<\/h4>\n<p><span style=\"font-family: courier new, courier;\">std::advance(iter, n)<\/span> puts its iterator<span style=\"font-family: courier new, courier;\"> iter n<\/span> position further. Depending on the iterator, the implementation can use pointer arithmetic or go <span style=\"font-family: courier new, courier;\">n<\/span> times further. In the first case, the execution time is constant; in the second case, the execution time depends on the stepsize <span style=\"font-family: courier new, courier;\">n<\/span>. Thanks to concepts, you can overload <span style=\"font-family: courier new, courier;\">std::advance<\/span> on the iterator category.<\/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>InputIterator I<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance(I<span style=\"color: #555555;\">&amp;<\/span> iter, <span style=\"color: #007788; font-weight: bold;\">int<\/span> n){...}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>BidirectionalIterator I<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance(I<span style=\"color: #555555;\">&amp;<\/span> iter, <span style=\"color: #007788; font-weight: bold;\">int<\/span> n){...}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>RandomAccessIterator I<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> advance(I<span style=\"color: #555555;\">&amp;<\/span> iter, <span style=\"color: #007788; font-weight: bold;\">int<\/span> n){...}\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ usage<\/span>\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> vec{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #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>};\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> vecIt <span style=\"color: #555555;\">=<\/span> vec.begin();\r\nstd<span style=\"color: #555555;\">::<\/span>advance(vecIt, <span style=\"color: #ff6600;\">5<\/span>);       <span style=\"color: #0099ff; font-style: italic;\">\/\/  RandomAccessIterator<\/span>\r\n\r\nstd<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> lst{<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>};\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> lstIt <span style=\"color: #555555;\">=<\/span> lst.begin();\r\nstd<span style=\"color: #555555;\">::<\/span>advance(lstIt, <span style=\"color: #ff6600;\">5<\/span>);       <span style=\"color: #0099ff; font-style: italic;\">\/\/  BidirectionalIterator<\/span>\r\n\r\nstd<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> forw{<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>};\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> forwIt <span style=\"color: #555555;\">=<\/span> forw.begin();\r\nstd<span style=\"color: #555555;\">::<\/span>advance(forwIt, <span style=\"color: #ff6600;\">5<\/span>);      <span style=\"color: #0099ff; font-style: italic;\">\/\/  InputIterator<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Based on the iterator category, the containers<span style=\"font-family: courier new, courier;\"> std::vector, std::list<\/span>, and<span style=\"font-family: courier new, courier;\"> std::forward_list<\/span> support, the best fitting <span style=\"font-family: courier new, courier;\">std::advance<\/span> implementation is used.<\/p>\n<h4>Specializations<\/h4>\n<p>Concepts also support template specializations.<\/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;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyVector<\/span>{};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>Object T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyVector<\/span>{};\r\n\r\nMyVector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> v1;     <span style=\"color: #0099ff; font-style: italic;\">\/\/ Object T<\/span>\r\nMyVector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;&gt;<\/span> v2;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ typename T<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li>\n<p><span style=\"font-family: courier new, courier;\">MyVector&lt;int&amp;&gt;<\/span> goes to the unconstrained template parameter.<\/p>\n<\/li>\n<li>\n<p><span style=\"font-family: courier new, courier;\">MyVector&lt;int&gt;<\/span> goes to the constrained template parameter.<\/p>\n<\/li>\n<\/ul>\n<h2>What&#8217;s next?<\/h2>\n<p>My <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-placeholder-syntax\">next post<\/a> is about syntactical unification in C++20. With C++20, you can use a constrained placeholder (concept) in each place. You could use an unconstrained placeholder (<span style=\"font-family: courier new, courier;\">auto<\/span>) in C++11. But this is not the end of the unification. Defining a template becomes with C++20 a piece of cake. Just use a constrained or an unconstrained placeholder to declare a function.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, C++20: Two Extremes and the Rescue with Concepts, I gave the first motivation for concepts. Concepts put semantic constraints on template parameters. Today, I present different use-cases for concepts in a compact form.<\/p>\n","protected":false},"author":21,"featured_media":5808,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[415],"class_list":["post-5817","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5817","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=5817"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5817\/revisions"}],"predecessor-version":[{"id":6764,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5817\/revisions\/6764"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5808"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5817"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}