{"id":6164,"date":"2021-06-17T06:28:24","date_gmt":"2021-06-17T06:28:24","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/template-argument-deduction-of-class-templates\/"},"modified":"2021-06-17T06:28:24","modified_gmt":"2021-06-17T06:28:24","slug":"template-argument-deduction-of-class-templates","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/template-argument-deduction-of-class-templates\/","title":{"rendered":"Template Argument Deduction of Class Templates"},"content":{"rendered":"<p>In my last post,<a href=\"https:\/\/www.modernescpp.com\/index.php\/template-arguments\"> Template Arguments<\/a>, I wrote about function template type deduction (C++98) and auto type deduction (C++11). Today I wear more modern hats. I start with automatic type deduction of non-type template parameters and class templates (C++17) and finish with automatic type deduction of concepts (C++20).<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6152\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/templatesArguments.png\" alt=\"\" width=\"650\" height=\"392\" style=\"display: block; margin-left: auto; margin-right: auto;\" data-alt=\"templatesArguments\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/templatesArguments.png 909w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/templatesArguments-300x181.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/templatesArguments-768x463.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Following the chronological order, let me start with two C++17 features: type deduction of non-type template parameters and type deduction of class templates in C++17.<\/p>\n<h2>Automatic type deduction of non-type template parameters<\/h2>\n<p>First of all. What are non-type template parameters? These are<code> nullptr<\/code>, integral values such as <code>bool<\/code>, and <code>int<\/code>, lvalue references, pointer, enumerations, and with C++20 floating-point values. Most of the time, integral types are used, and so do I.<\/p>\n<p>After this theory, let&#8217;s start with an example.<\/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: 0px; 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;\">auto<\/span> N<span style=\"color: #555555;\">&gt;          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyClass<\/span>{\r\n    ....\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> N<span style=\"color: #555555;\">&gt;<\/span>         <span style=\"color: #0099ff;\"> \/\/ (2)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">MyClass<\/span><span style=\"color: #555555;\">&lt;<\/span>N<span style=\"color: #555555;\">&gt;<\/span> {\r\n    ....\r\n};\r\n\r\n\r\nMyClass<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #cc3300;\">'x'<\/span><span style=\"color: #555555;\">&gt;<\/span> myClass1;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\nMyClass<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">2017<\/span><span style=\"color: #555555;\">&gt;<\/span>  myClass2;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>By using <span style=\"font-family: courier new,courier;\">auto<\/span> in (1) in the template signature,&nbsp; <span style=\"font-family: courier new,courier;\">N<\/span> is a non-type template parameter. The compiler will automatically deduce it. You can also partially specialize for <span style=\"font-family: courier new,courier;\">int <\/span>(2). The template instantiation (3) will use the primary template (1), and the following template instantiation the partial specialization for<span style=\"font-family: courier new,courier;\"> int <\/span>(4).<span style=\"font-family: courier new,courier;\"><br \/><\/span><\/p>\n<p>The usual type modifiers can be used to constrain the type of the non-type 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><span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> p<span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> S;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In this declaration of a class template<code> S<\/code>, <span style=\"font-family: courier new,courier;\">p<\/span> must be a pointer to <span style=\"font-family: courier new,courier;\">const.<\/span><\/p>\n<p>The automatic type deduction for non-type templates can also be applied to variadic templates.<\/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;\">auto<\/span>... ns<span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">VariadicTemplate<\/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;\">auto<\/span> n1, decltype(n1)... ns<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">TypedVariadicTemplate<\/span>{ .... };\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">VariadicTemplate<\/span> can deduce an arbitrary number of non-type template parameters. <span style=\"font-family: courier new,courier;\">TypeVariadicTemplate<\/span> will only deduce the first template parameter. The remaining templated parameters will be of the same type as the first type:<code> decltype(n1)<\/code>.<\/p>\n<p>Automatic type deduction from class templates makes the usage of class templates quite comfortable.<\/p>\n<\/p>\n<h2>Automatic Type Deduction of Class Templates<\/h2>\n<p>A function template can deduce its type parameters from its function arguments. But that was not possible for particular functions: constructors of class templates. With C++17, this statement is simply wrong. A constructor can deduce its type parameters from its constructor arguments. Here is the first example.<\/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;\">\/\/ templateArgumentDeduction.cpp<\/span>\r\n\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> T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> showMe(<span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&amp;<\/span> t) {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> t <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\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: #006699; font-weight: bold;\">struct<\/span> ShowMe{\r\n    ShowMe(<span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&amp;<\/span> t) {\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> t <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/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    showMe(<span style=\"color: #ff6600;\">5.5<\/span>);          <span style=\"color: #0099ff; font-style: italic;\">\/\/ not showMe&lt;double&gt;(5.5);<\/span>\r\n    showMe(<span style=\"color: #ff6600;\">5<\/span>);            <span style=\"color: #0099ff; font-style: italic;\">\/\/ not showMe&lt;int&gt;(5);<\/span>\r\n    \r\n    ShowMe(<span style=\"color: #ff6600;\">5.5<\/span>);          <span style=\"color: #0099ff; font-style: italic;\">\/\/ not ShowMe&lt;double&gt;(5.5);<\/span>\r\n    ShowMe(<span style=\"color: #ff6600;\">5<\/span>);            <span style=\"color: #0099ff; font-style: italic;\">\/\/ not ShowMe&lt;int&gt;(5);<\/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>Let me say a few words about the <code>main<\/code> function. The instantiation of the function template <code>showMe<\/code> <code><\/code>has been valid since the first C++ standard C++98, but the instantiation of the class template <code>ShowMe<\/code> since C++17. From the user&#8217;s perspective, using functions templates or class templates feels just like an ordinary function or class.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5551\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/templateArgumentDeduction.png\" alt=\"templateArgumentDeduction\" width=\"482\" height=\"271\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>Maybe, you are not convinced. Here are more examples of class template argument deduction.<\/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;\">\/\/ classTemplateArgumentDeduction.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;array&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;mutex&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;memory&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>array myArr{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>};          <span style=\"color: #0099ff; font-style: italic;\">\/\/ deduces std::array&lt;int, 3&gt; <\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>vector myVec{<span style=\"color: #ff6600;\">1.5<\/span>, <span style=\"color: #ff6600;\">2.5<\/span>};        <span style=\"color: #0099ff; font-style: italic;\">\/\/ deduces std::vector&lt;double&gt;<\/span>\r\n \r\n    std<span style=\"color: #555555;\">::<\/span>mutex mut;\r\n    std<span style=\"color: #555555;\">::<\/span>lock_guard myLock(mut);       <span style=\"color: #0099ff; font-style: italic;\">\/\/ deduces std::lock_guard&lt;mutex&gt;(mut);<\/span>\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>pair myPair(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>);          <span style=\"color: #0099ff; font-style: italic;\">\/\/ deduces std::pair&lt;int, double&gt;<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>tuple myTup(<span style=\"color: #ff6600;\">5<\/span>, myArr, myVec); <span style=\"color: #0099ff; font-style: italic;\">\/\/ deduces std::tuple&lt;int, <\/span>\r\n                                       <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::array&lt;int, 3&gt;, std::vector&lt;double&gt;&gt;<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The comments show the C++17 compiler deduced types. Thanks to<a href=\"https:\/\/cppinsights.io\/s\/b83f6def\"> C++ Insights<\/a>, you can visualize this process of template argument deduction.<\/p>\n<p>The last two examples to std::pair and std::tuple are pretty interesting. Before C++17, we used factory functions such as std::make_pair or std::make_tuple to create a std::pair or a std::tuple without specifying the type parameters. In contrast to class templates, the compiler could deduce the type parameter from the function arguments. Here is a simplified version of <code>std::pair<\/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;\">\/\/ makePair.cpp<br \/><\/span>\r\n<span style=\"color: #009999;\">#include &lt;utility&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> T1, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>\r\nstd<span style=\"color: #555555;\">::<\/span>pair<span style=\"color: #555555;\">&lt;<\/span>T1, T2<span style=\"color: #555555;\">&gt;<\/span> make_pair2(T1 t1, T2 t2) { \r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>pair<span style=\"color: #555555;\">&lt;<\/span>T1, T2<span style=\"color: #555555;\">&gt;<\/span>(t1, t2); \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main() {\r\n\t\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span> arg{<span style=\"color: #ff6600;\">5.5<\/span>};\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span> pair1 <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>make_pair(<span style=\"color: #ff6600;\">5<\/span>, arg);\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span> pair2 <span style=\"color: #555555;\">=<\/span> make_pair2(<span style=\"color: #ff6600;\">5<\/span>, arg);\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span> pair3 <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>pair(<span style=\"color: #ff6600;\">5<\/span>, arg);\r\n   \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The compiler deduces the same type for<code> pair1<\/code> and<code> pair2<\/code>. With C++17, we don&#8217;t need this factory function anymore and can directly invoke the constructor of <code>std::pair<\/code> to get<code> pair3<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6162\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/makePair.png\" alt=\"makePair\" width=\"500\" height=\"466\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/makePair.png 758w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/makePair-300x280.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>You can study the program on <a href=\"https:\/\/cppinsights.io\/s\/513635bd\">C++ Insights<\/a>.<\/p>\n<p>You may wonder why my function template<code> make_pair2<\/code> took its arguments by value.<code> std::make_pair<\/code> decays its arguments, and so does my function template<code> make_pair2<\/code>. I wrote about the decay of function arguments in my last post <a href=\"https:\/\/www.modernescpp.com\/index.php\/template-arguments\">Template Arguments<\/a>.<\/p>\n<p>Before I write a few words about the automatic type deduction with concepts, I want to emphasize is explicit. Automatic type deduction is more than convenient. It&#8217;s a security feature.<strong> You cannot make an error when you don&#8217;t specify the type.<\/strong><\/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;\">\/\/ automaticTypeDeduction.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;string&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\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> func(T) {};\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: #006699; font-weight: bold;\">struct<\/span> Class{\r\n  Class(T){}\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n  \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> a1 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5.5<\/span>;              <span style=\"color: #0099ff; font-style: italic;\">\/\/ static_cast&lt;int&gt;(5.5)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> a2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">5.5<\/span>;\r\n  \r\n    func<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">float<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5.5<\/span>);          <span style=\"color: #0099ff; font-style: italic;\">\/\/ static_cast&lt;float&gt;(5.5)<\/span>\r\n    func(<span style=\"color: #ff6600;\">5.5<\/span>);\r\n  \r\n    Class<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> class1(<span style=\"color: #cc3300;\">\"class\"<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/\/ calls essentially std::string(\"class\")<\/span>\r\n    Class class2(<span style=\"color: #cc3300;\">\"class\"<\/span>);\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>All errors are only because I explicitly specified the type:<\/p>\n<ul>\n<li><code>int a1<\/code> triggers the narrowing conversion from <code>double<\/code> to<code> int<\/code><\/li>\n<li><code>func&lt;float&gt;(5.5)<\/code> causes the conversion from the <code>double<\/code> value<code> 5.5<\/code> to <code>float<\/code><\/li>\n<li><code>Class&lt;std::string&gt; class1(\"class\")<\/code> creates a C++-string initialized with a C-string.<\/li>\n<\/ul>\n<p>If you want to study the program, here it is: <a href=\"https:\/\/cppinsights.io\/s\/c8c70e7c\">C++ Insights<\/a>.<\/p>\n<p>There is not much to add to the story of automatic type deduction when concepts come into play.<\/p>\n<h2>Automatic Type Deduction with Concepts<\/h2>\n<p>Automatic type deduction with concepts work like expected:<\/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;\">\/\/ typeDeductionConcepts.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;concepts&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">foo<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> t) {}                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">bar<\/span>(std<span style=\"color: #555555;\">::<\/span>integral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> t){}     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>regular T<span style=\"color: #555555;\">&gt;<\/span>            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Class{\r\n  Class(T){}\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    foo(<span style=\"color: #ff6600;\">5.5<\/span>);\r\n    bar(<span style=\"color: #ff6600;\">5<\/span>);\r\n    Class cl(<span style=\"color: #336666;\">true<\/span>);\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Whether you use an unconstrained placeholder (<code>auto<\/code> in line 1), a constrained placeholder (a concept in line 2), or a restricted template parameter (a concept in line 3), the compiler deduces the expected type. <a href=\"https:\/\/cppinsights.io\/s\/218e9e55\">C++ Insights<\/a> helps to visualize the type deduction.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6163\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/typeDeductionConcepts.png\" alt=\"typeDeductionConcepts\" width=\"500\" height=\"745\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/typeDeductionConcepts.png 583w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/typeDeductionConcepts-201x300.png 201w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>In my<a href=\"https:\/\/www.modernescpp.com\/index.php\/template-specialization\"> next post,<\/a> I will write about the next exciting feature of templates: specialization. You can fully specialize a function template or class template. Additionally, a class template can be partially specialized.<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, Template Arguments, I wrote about function template type deduction (C++98) and auto type deduction (C++11). Today I wear more modern hats. I start with automatic type deduction of non-type template parameters and class templates (C++17) and finish with automatic type deduction of concepts (C++20).<\/p>\n","protected":false},"author":21,"featured_media":6152,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[],"class_list":["post-6164","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6164","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=6164"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6164\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6152"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}