{"id":6238,"date":"2021-10-15T06:17:59","date_gmt":"2021-10-15T06:17:59","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/automatic-return-type\/"},"modified":"2023-06-26T09:24:48","modified_gmt":"2023-06-26T09:24:48","slug":"automatic-return-type","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/automatic-return-type\/","title":{"rendered":"Automatic Return Type (C++98)"},"content":{"rendered":"<p>Depending on the used C++ standard, there are different ways to return the correct return type of a function template. In this post, I start with traits (C++98), continue in my next post with C++11\/14, and end with concepts (C++20).<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6233\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/AutomaticReturnType.png\" alt=\"AutomaticReturnType\" width=\"650\" height=\"398\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/AutomaticReturnType.png 914w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/AutomaticReturnType-300x184.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/AutomaticReturnType-768x471.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Here is the challenge for today&#8217;s post.<\/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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #555555;\">???<\/span> sum(T t, T2 t2) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> t <span style=\"color: #555555;\">+<\/span> t2;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>When you have a function template, such as <code>sum<\/code> with at least two type parameters, you can not decide, in general, the return type of the function. Of course, <code>sum&nbsp;<\/code>should return the type that the arithmetic operation<code> t + t2 <\/code>provides. Here are a few examples using <a href=\"https:\/\/en.wikipedia.org\/wiki\/Run-time_type_information\">run-time type information (RTTI)<\/a> with <code>std::type_info.<\/code><\/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;\">\/\/ typeinfo.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&gt;<\/span>\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\t\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    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(5.5 + 5.5).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(<span style=\"color: #ff6600;\">5.5<\/span> <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">5.5<\/span>).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(5.5 + true).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(<span style=\"color: #ff6600;\">5.5<\/span> <span style=\"color: #555555;\">+<\/span> <span style=\"color: #336666;\">true<\/span>).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(true + 5.5).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(<span style=\"color: #336666;\">true<\/span> <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">5.5<\/span>).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(true + false).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(<span style=\"color: #336666;\">true<\/span> <span style=\"color: #555555;\">+<\/span> <span style=\"color: #336666;\">false<\/span>).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/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>I executed the program on Windows using MSVC because MSVC produces in contrast to GCC or Clang human-readable names.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6234\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/typeinfo.png\" alt=\"typeinfo\" width=\"351\" height=\"189\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/typeinfo.png 351w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/typeinfo-300x162.png 300w\" sizes=\"auto, (max-width: 351px) 100vw, 351px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Adding two <code>double<\/code>s returns a <code>double<\/code>, adding a <code>double<\/code> and a <code>bool<\/code> returns a <code>bool<\/code>, and adding two <code>bool<\/code>s returns an <code>int<\/code>.<\/p>\n<p>I use in my examples only<a href=\"https:\/\/en.cppreference.com\/w\/c\/language\/arithmetic_types\"> arithmetic types<\/a>. You must extend my solutions if you want to apply my examples to user-defined that support arithmetic operations.<\/p>\n<p>Now, my journey starts with C++98.<\/p>\n<\/p>\n<h2>C++98<\/h2>\n<p>Honestly, C++98 provides no general solution for returning the correct type. Essentially, you must implement the type-deduction rules using a technique called<a href=\"https:\/\/accu.org\/journals\/overload\/9\/43\/frogley_442\/\"> traits<\/a>, also known as template traits. A traits class provides valuable information about template parameters and can be used instead of the template parameters.<\/p>\n<p>The following class <code>ResultType<\/code> provides a type-to-type mapping using full template specialization.<\/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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ traits.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ primary template (1)<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType;       \r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span>  <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for double, double<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/  full specialization for double, bool<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;        <span style=\"color: #0099ff;\"> \/\/ (2)<\/span>\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for bool, double<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for bool, bool<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> Type;\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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>  \r\n<span style=\"color: #006699; font-weight: bold;\">typename<\/span> ReturnType<span style=\"color: #555555;\">&lt;<\/span>T, T2<span style=\"color: #555555;\">&gt;::<\/span>Type sum(T t, T2 t2) {  <span style=\"color: #0099ff;\"> \/\/ (3)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> t <span style=\"color: #555555;\">+<\/span> t2;\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> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(5.5, 5.5)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(5.5, true)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #336666;\">true<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(true, 5.5)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(true, false)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #336666;\">false<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/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>Line (1) is the primary template or general template. The primary template has to be declared before the following full specializations. A declaration such as in line 1 is acceptable if the primary template is unnecessary. The following lines provide the full specializations for <code>&lt;double, double&gt;<\/code> , for <code>&lt;double, bool&gt;<\/code>, for<code> &lt;bool, double&gt;<\/code>, and for<code> &lt;bool, bool&gt;<\/code>. You can read more details about template specialization in my previous posts:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/template-specialization\">Template Specialization<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/template-specialization-more-details\">Template Specialization &#8211; More Details about Class Templates<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/full-specialization-of-function-templates\">Full Specialization of Function Templates<\/a><\/li>\n<\/ul>\n<p>The critical observation in the various full specializations of <code>ReturnType<\/code> is that they all have an alias <code>Type<\/code> such as<code> typedef double Type<\/code> (line 2). This alias is the return type of the function template <code>sum<\/code> (line 3): <code>typename ReturnType&lt;T, T2&gt;::type<\/code>.<\/p>\n<p>The traits work as expected.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6235\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traits.png\" alt=\"traits\" width=\"532\" height=\"189\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traits.png 532w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traits-300x107.png 300w\" sizes=\"auto, (max-width: 532px) 100vw, 532px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>You may be wondering why I used <code>typename<\/code> in the return type expression of the function template<code> sum<\/code>. At least one reader of my previous post about <code>Dependent Names<\/code> asked me when to apply <code>typename<\/code> or <code>.template <\/code>to templates.<code> <\/code><code><\/code> The short answer is that the compiler can not decide if the expression<code> ReturnType<span style=\"color: #555555;\">&lt;<\/span>T, T2<span style=\"color: #555555;\">&gt;::<\/span>Type <\/code>is a type (such as in this case), a non-type, or a template. Using <code>typename<\/code> before <code>ReturnType&lt;T, T2&gt;::Type<\/code> gives the compiler the crucial hint. You can read the long answer in my previous post <a href=\"https:\/\/www.modernescpp.com\/index.php\/dependent-types\">Dependent Names<\/a>.<\/p>\n<h3>Missing Overload<\/h3>\n<p>Initially, I wanted to continue my post and write about C++11. Still, I assume you have another question: What happens when I invoke the function template <code>sum<\/code> with arguments for which not partial template specialization is defined? Let me try it out with<code> sum(5.5f, 5)<\/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;\">\/\/ traitsError.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ primary template<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType;       \r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span>  <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for double, double<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/  full specialization for double, bool<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for bool, double<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for bool, bool<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> Type;\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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>  \r\n<span style=\"color: #006699; font-weight: bold;\">typename<\/span> ReturnType<span style=\"color: #555555;\">&lt;<\/span>T, T2<span style=\"color: #555555;\">&gt;::<\/span>Type sum(T t, T2 t2) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> t <span style=\"color: #555555;\">+<\/span> t2;\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> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(5.5f, 5.5)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #ff6600;\">5.5f<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/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>Many C++ programmers expect that the float value <code>5.5f<\/code> is converted to an <code>double<\/code> and the full specialization for <code>&lt;double, double&gt;<\/code> is used.&nbsp;<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6236\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsError.png\" alt=\"traitsError\" width=\"650\" height=\"195\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsError.png 949w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsError-300x90.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsError-768x231.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>NO! The types must match exactly. The MSVC compiler gives an exact error message. There is no overload <code>sum<\/code> for<code> T = float<\/code> and<code> T2 = double<\/code> available. The primary template is not defined and can not be instantiated.<\/p>\n<p><strong>Types do not convert; only expressions such as values can be converted: <code>double res&nbsp; = 5.5f + 5.5<\/code>;<\/strong><\/p>\n<h3>Default Return Type<\/h3>\n<p>When you make out of the declaration of the primary template a definition, the primary template becomes the default case. Consequently, the following implementation of <code>ReturnType<\/code> uses<code> long double<\/code> as the default return type.<\/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: #0099ff; font-style: italic;\">\/\/ traitsDefault.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ primary template<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;    <em> <span style=\"color: #0099ff;\"><\/span><\/em>\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span>  <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for double, double<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/  full specialization for double, bool<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for bool, double<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">double<\/span> Type;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;&gt;<\/span> <span style=\"color: #0099ff; font-style: italic;\">\/\/ full specialization for bool, bool<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ReturnType <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span><span style=\"color: #555555;\">&gt;<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span> Type;\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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>  \r\n<span style=\"color: #006699; font-weight: bold;\">typename<\/span> ReturnType<span style=\"color: #555555;\">&lt;<\/span>T, T2<span style=\"color: #555555;\">&gt;::<\/span>Type sum(T t, T2 t2) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> t <span style=\"color: #555555;\">+<\/span> t2;\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> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(5.5, 5.5)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(5.5, true)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #ff6600;\">5.5<\/span>, <span style=\"color: #336666;\">true<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(true, 5.5)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(true, false)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #336666;\">true<\/span>, <span style=\"color: #336666;\">false<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"typeid(sum(5.5f, 5.5)).name(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(sum(<span style=\"color: #ff6600;\">5.5f<\/span>, <span style=\"color: #ff6600;\">5.5<\/span>)).name() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/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>The invocation of<code> sum(5.5f, 5.f)<\/code> causes the instantiation of the primary template.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6237\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsDefault.png\" alt=\"traitsDefault\" width=\"458\" height=\"217\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsDefault.png 458w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/10\/traitsDefault-300x142.png 300w\" sizes=\"auto, (max-width: 458px) 100vw, 458px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h3>What&#8217;s next?<\/h3>\n<p>In C++11, there are various ways to deduce the return type automatically. C++14 adds syntactic sugar to these techniques, and C++20 enables it to write it very explicitly. Read more about the improvements in my next post.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Depending on the used C++ standard, there are different ways to return the correct return type of a function template. In this post, I start with traits (C++98), continue in my next post with C++11\/14, and end with concepts (C++20).<\/p>\n","protected":false},"author":21,"featured_media":6233,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[436],"class_list":["post-6238","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates","tag-auto"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6238","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=6238"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6238\/revisions"}],"predecessor-version":[{"id":6696,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6238\/revisions\/6696"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6233"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6238"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6238"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}