{"id":5566,"date":"2018-11-28T21:28:10","date_gmt":"2018-11-28T21:28:10","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-argument-dependent-lookup-or-koenig-lookup\/"},"modified":"2023-06-26T10:17:53","modified_gmt":"2023-06-26T10:17:53","slug":"c-core-guidelines-argument-dependent-lookup-or-koenig-lookup","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-argument-dependent-lookup-or-koenig-lookup\/","title":{"rendered":"C++ Core Guidelines: Surprises with Argument-Dependent Lookup"},"content":{"rendered":"<p>There is, in particular, one rule left to template interfaces which are quite interesting: T.47: Avoid highly visible unconstrained templates with common names. Admittedly, the rule T47 is often the reason for unexpected behavior because the wrong function is called.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5562\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/cat-633081_1280.jpg\" alt=\"cat 633081 1280\" width=\"500\" height=\"375\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/cat-633081_1280.jpg 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/cat-633081_1280-300x225.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/cat-633081_1280-1024x768.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/cat-633081_1280-768x576.jpg 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Although I write today mainly about rule T.47, I have more to say.<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-visible\">T.47: Avoid highly visible unconstrained templates with common names<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-concept-def\">T.48: If your compiler does not support concepts, fake them with <code class=\"highlighter-rouge no-highlight\">enable_if<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-erasure\">T.49: Where possible, avoid type-erasure<\/a><\/li>\n<\/ul>\n<p>The get to the point of rule T.47, I have to make a short detour. This detour is about argument-dependent lookup (ADL) also known as Koenig lookup named after <a href=\"https:\/\/en.wikipedia.org\/wiki\/Andrew_Koenig_(programmer)\">Andrew Koenig<\/a>. First of all. What is an argument-dependent lookup?<\/p>\n<h2>Argument-Dependent Lookup (ADL)<\/h2>\n<p>Here is the definition of ADL:<\/p>\n<ul>\n<li><strong>Argument-dependent lookup<\/strong> is a set of rules for looking up unqualified function names. Unqualified function names are additionally looked up in the namespace of their arguments.\n<\/li>\n<\/ul>\n<p>Unqualified function names mean functions without the<code class=\"highlighter-rouge\"> <\/code>scope&nbsp;operator (::).. Is argument-dependent lookup bad? Of course not; ADL makes our life as a programmer easier. Here is an example.<\/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: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Argument-dependent lookup\"<\/span>;  \r\n}\t\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Fine. Let me remove the syntactic sugar of operator overloading and use the function call directly.<\/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: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n    <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">&lt;&lt;<\/span>(std<span style=\"color: #555555;\">::<\/span>cout, <span style=\"color: #cc3300;\">\"Argument-dependent lookup\"<\/span>);\r\n}\t\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>This equivalent program shows what is happening under the hood. The function <span style=\"font-family: courier new, courier;\">operator&lt;&lt;<\/span> is called with the arguments <span style=\"font-family: courier new, courier;\">std::<\/span>cout and a C-string <span style=\"font-family: courier new, courier;\">&#8220;Argument-dependent lookup&#8221;<\/span>.<\/p>\n<p>Fine? No? The question arises: Where is the definition of the function<span style=\"font-family: courier new, courier;\"> operator&lt;&lt;<\/span>. Of course, there is no definition in the global namespace. <span style=\"font-family: courier new, courier;\">operator&lt;&lt;<\/span> is an unqualified function name; therefore, argument-dependent lookup kicks in. The function name is additionally looked up in the namespace of their arguments.&nbsp; In this particular case, the namespace <span style=\"font-family: courier new, courier;\">std<\/span> is due to the first argument <span style=\"font-family: courier new, courier;\">std::cout<\/span> considered, and the lookup finds the appropriate candidate: <span class=\"co1\" style=\"font-family: courier new, courier;\">std::operator&lt;&lt;(std::ostream&amp;, const char*). <\/span><span class=\"co1\">Often ADL provides you precisely with the function you are looking for, but sometimes&#8230;&nbsp; <\/span><\/p>\n<p>Now, it is the right time to write about rule T.47:<\/p>\n<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-visible\">T.47: Avoid highly visible unconstrained templates with common names<\/a><\/h2>\n<p>In the expression<span style=\"font-family: courier new, courier;\"> std::cout &lt;&lt; &#8220;Argument-dependent lookup&#8221;<\/span>, the overloaded output operator <span style=\"font-family: courier new, courier;\">&lt;&lt;<\/span>&nbsp; is the obvious common name because it is defined in the namespace <span style=\"font-family: courier new, courier;\">std<\/span>. The following program, based on the program of the core guidelines, shows the crucial point of this rule.<\/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: #0099ff; font-style: italic;\">\/\/ argumentDependentLookup.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">namespace<\/span> Bad{\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">struct<\/span> Number{ \r\n        <span style=\"color: #007788; font-weight: bold;\">int<\/span> m; \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> T1, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ generic equality  (5)<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(T1, T2){ \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">false<\/span>;  \r\n    }\r\n    \r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">namespace<\/span> Util{\r\n    \r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, Bad<span style=\"color: #555555;\">::<\/span>Number){   <span style=\"color: #0099ff; font-style: italic;\">\/\/ equality to int (4)<\/span>\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">true<\/span>; \r\n    } \r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> compareSize(){\r\n        Bad<span style=\"color: #555555;\">::<\/span>Number badNumber{<span style=\"color: #ff6600;\">5<\/span>};                            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\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> 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>};\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;\">\"5 == badNumber: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>                    \r\n                     (<span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">==<\/span> badNumber) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;          <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> <span style=\"color: #cc3300;\">\"vec.size() == badNumber: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> \r\n                     (vec.size() <span style=\"color: #555555;\">==<\/span> badNumber) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\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\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n   \r\n   Util<span style=\"color: #555555;\">::<\/span>compareSize();\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I expect that in both cases (2 and 3), the overloaded <span style=\"font-family: courier new, courier;\">operator ==<\/span> in Line (4) is called because it takes an argument of type <span style=\"font-family: courier new, courier;\">Bad::Number<\/span> (1)<span style=\"font-family: courier new, courier;\">; <\/span>therefore, I should get two times<span style=\"font-family: courier new, courier;\"> true.<\/span><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5563\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookup.png\" alt=\"argumentDependentLookup\" width=\"400\" height=\"175\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookup.png 780w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookup-300x131.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookup-768x336.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>What happened here? The call in line (3) is resolved by the generic equality operator in line (5)? The reason for my surprise is that <span style=\"font-family: courier new, courier;\">vec.size()<\/span> returns a value of type <span style=\"font-family: courier new, courier;\">std::size_type<\/span>, which is an unsigned integer type. This means the equality operator requires a conversation to int <code>in<\/code> line (4). This is unnecessary for the generic equality in line (5) because this is a fit without conversion. Thanks to argument-dependent lookup, the generic equality operator belongs to the set of possible overloads.<\/p>\n<p>The rule states &#8220;Avoid highly visible unconstrained templates with common names&#8221;. Let me see what would happen if I followed the rule and disable the generic equality operator. Here is the fixed 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: #0099ff; font-style: italic;\">\/\/ argumentDependentLookupResolved.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">namespace<\/span> Bad{\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">struct<\/span> Number{ \r\n        <span style=\"color: #007788; font-weight: bold;\">int<\/span> m; \r\n    };\r\n    \r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">namespace<\/span> Util{\r\n    \r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, Bad<span style=\"color: #555555;\">::<\/span>Number){   <span style=\"color: #0099ff; font-style: italic;\">\/\/ compare to int (4)<\/span>\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #336666;\">true<\/span>; \r\n    } \r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> compareSize(){\r\n        Bad<span style=\"color: #555555;\">::<\/span>Number badNumber{<span style=\"color: #ff6600;\">5<\/span>};                            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\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> 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>};\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;\">\"5 == badNumber: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>                    \r\n                     (<span style=\"color: #ff6600;\">5<\/span> <span style=\"color: #555555;\">==<\/span> badNumber) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;          <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> <span style=\"color: #cc3300;\">\"vec.size() == badNumber: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> \r\n                     (vec.size() <span style=\"color: #555555;\">==<\/span> badNumber) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl; <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\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\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n   \r\n   Util<span style=\"color: #555555;\">::<\/span>compareSize();\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the result matches my expectations.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5564\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookupResolved.png\" alt=\"argumentDependentLookupResolved\" width=\"450\" height=\"171\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookupResolved.png 895w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookupResolved-300x114.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/argumentDependentLookupResolved-768x293.png 768w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>&nbsp;Here are my remarks on the last two rules for template interfaces.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-concept-def\">T.48: If your compiler does not support concepts, fake them with <code class=\"highlighter-rouge no-highlight\">enable_if<\/code><\/a><\/h2>\n<p>When I present <span style=\"font-family: courier new, courier;\">std::enable_if<\/span> in my seminars, a few participants are slightly scared. Here is the simplified version of a generic greatest common divisor algorithm.<\/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;\">\/\/ enable_if.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\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: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n         <span style=\"color: #006699; font-weight: bold;\">typename<\/span> std<span style=\"color: #555555;\">::<\/span>enable_if<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value, T<span style=\"color: #555555;\">&gt;::<\/span>type<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span><span style=\"color: #555555;\">&gt;<\/span>       \r\nT gcd(T a, T b){\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> a; }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span>{\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> gcd(b, a <span style=\"color: #555555;\">%<\/span> b);                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    }\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>endl;\r\n                                                           <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> <span style=\"color: #cc3300;\">\"gcd(100, 10)= \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  gcd(<span style=\"color: #ff6600;\">100<\/span>, <span style=\"color: #ff6600;\">10<\/span>)  <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gcd(3.5, 4)= \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> gcd(<span style=\"color: #ff6600;\">3.5<\/span>, <span style=\"color: #ff6600;\">4.0<\/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> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The algorithm is way too generic. It should only work for integral types. Now, <span style=\"font-family: courier new, courier;\">std::enable_if<\/span> from the<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\"> type-traits <\/a>library in line (1) comes to my rescue.<\/p>\n<p>The expression <span style=\"font-family: courier new,courier;\">std::is_integral<\/span> (line 2) is critical for understanding the program. This line determines whether the type parameter T is integral. If T is not integral and, therefore, the return value <span style=\"font-family: courier new,courier;\">false<\/span>, there will be no template instantiations for this specific type.<\/p>\n<p>Only if <span style=\"font-family: courier new,courier;\">std::is_integral<\/span>&nbsp;returns <span style=\"font-family: courier new,courier;\">true&nbsp;<\/span><span style=\"font-family: courier new,courier;\">std::enable_if<\/span> has a public member typedef <span style=\"font-family: courier new,courier;\">type.<\/span> Suppose line (1) is not valid. But this is not an error.&nbsp;<span style=\"font-family: courier new,courier;\"> <\/span><\/p>\n<p>The C++ standard says:&nbsp;When substituting the deduced type for the template parameter fails, the specialization is discarded from the overload set instead of causing a compile error. There is a shorter acronym for this rule <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/sfinae\">SFINAE<\/a> (<strong>S<\/strong>ubstitution<strong> F<\/strong>ailure <strong>I<\/strong>s <strong>N<\/strong>ot <strong>A<\/strong>n <strong>E<\/strong>rror).<\/p>\n<p>The compilation output (<span style=\"font-family: courier new, courier;\">enable_if.cpp: 20:49<\/span>) shows it. There is no template specialization for the type <span style=\"font-family: courier new,courier;\">double <\/span>available.&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5565\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/enable_if.png\" alt=\"enable if\" width=\"600\" height=\"230\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/enable_if.png 1397w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/enable_if-300x115.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/enable_if-1024x393.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/11\/enable_if-768x295.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>But the output shows more. (<span style=\"font-family: courier new, courier;\">enable_if.cpp:7:71<\/span>): &#8220;<span style=\"font-family: courier new, courier;\">no named `type* in struct std::enable_if&lt;false, double&gt;<\/span>&#8220;.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-erasure\">T.49: Where possible, avoid type-erasure<\/a><\/h2>\n<p>Strange, I wrote two posts to type-erasure (<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-type-erasure\" class=\"postid398\">C++ Core Guidelines: Type Erasure<\/a> and <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-type-erasure-with-templates\" class=\"postid399\">C++ Core Guidelines: Type Erasure with Templates<\/a>) and explained this quite challenging technique. Now, I should avoid it, when possible.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>With my <a href=\"http:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-template-definitons\">next post<\/a>, I jump from the interfaces of templates to their definition.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There is, in particular, one rule left to template interfaces which are quite interesting: T.47: Avoid highly visible unconstrained templates with common names. Admittedly, the rule T47 is often the reason for unexpected behavior because the wrong function is called.<\/p>\n","protected":false},"author":21,"featured_media":5562,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[476],"class_list":["post-5566","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-adl"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5566","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=5566"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5566\/revisions"}],"predecessor-version":[{"id":6802,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5566\/revisions\/6802"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5562"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}