{"id":6256,"date":"2021-11-26T07:53:03","date_gmt":"2021-11-26T07:53:03","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-type-comparisons\/"},"modified":"2023-06-26T09:21:51","modified_gmt":"2023-06-26T09:21:51","slug":"the-type-traits-library-type-comparisons","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-type-comparisons\/","title":{"rendered":"The Type-Traits Library: Type Comparisons"},"content":{"rendered":"<p>In my last post, &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/the-type-traits-library-type-checks\">The Type-Traits Library: Type Checks<\/a>&#8221; I introduced type checks at compile time with the type-traits library. Today, I write about type comparisons at compile time.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6251\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/templatesTypeTraits.png\" alt=\"templatesTypeTraits\" width=\"650\" height=\"412\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/templatesTypeTraits.png 918w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/templatesTypeTraits-300x190.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/templatesTypeTraits-768x487.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>The type-traits library empowers you to compare types at compile time. Compile time means that there are no costs involved at run time.<\/p>\n<h2>Comparing types<\/h2>\n<p>The type-traits library supports in C++11 three kinds of comparisons:<\/p>\n<ul>\n<li><span style=\"font-family: courier new,courier;\">is_base_of&lt;Base, Derived&gt;<\/span><\/li>\n<li><span style=\"font-family: courier new,courier;\">is_convertible&lt;From, To&gt;<\/span><\/li>\n<li><span style=\"font-family: courier new,courier;\">is_same&lt;T, U&gt;<\/span><\/li>\n<\/ul>\n<p>With C++20, we additionally got<\/p>\n<ul>\n<li><span style=\"font-family: courier new,courier;\">is_pointer_interconvertible_with_class&lt;From, To&gt;<\/span><\/li>\n<li><span style=\"font-family: courier new,courier;\">is_pointer_interconvertible_base_of&lt;Base, Derived&gt;<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>For simplicity reasons, I write only about the C++11 metafunctions.<\/p>\n<p>Thanks to its member <span style=\"font-family: courier new,courier;\">value<\/span>, each class template returns true or false and is the optimal fit for <span style=\"font-family: courier new,courier;\"><a href=\"https:\/\/www.modernescpp.com\/index.php\/statically-checked\">static_assert.<\/a><\/span><\/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;\">\/\/ compare.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;cstdint&gt;<\/span>\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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Base<\/span>{};\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Derived<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Base{};\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> std<span style=\"color: #555555;\">::<\/span>boolalpha <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;\">\"std::is_base_of&lt;Base,Derived&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_base_of<span style=\"color: #555555;\">&lt;<\/span>Base,Derived<span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_base_of&lt;Derived,Base&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_base_of<span style=\"color: #555555;\">&lt;<\/span>Derived,Base<span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_base_of&lt;Derived,Derived&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_base_of<span style=\"color: #555555;\">&lt;<\/span>Derived,Derived<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ static_assert(std::is_base_of&lt;Derived,Base&gt;::value,\"Derived is not base of Base\");                  \/\/ (1) <\/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  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"std::is_convertible&lt;Base*,Derived*&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_convertible<span style=\"color: #555555;\">&lt;<\/span>Base<span style=\"color: #555555;\">*<\/span>,Derived<span style=\"color: #555555;\">*&gt;::<\/span>value <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;\">\"std::is_convertible&lt;Derived*,Base*&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_convertible<span style=\"color: #555555;\">&lt;<\/span>Derived<span style=\"color: #555555;\">*<\/span>,Base<span style=\"color: #555555;\">*&gt;::<\/span>value <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;\">\"std::is_convertible&lt;Derived*,Derived*&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_convertible<span style=\"color: #555555;\">&lt;<\/span>Derived<span style=\"color: #555555;\">*<\/span>,Derived<span style=\"color: #555555;\">*&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ static_assert(std::is_convertible&lt;Base*,Derived*&gt;::value,\"Base* can not be converted to Derived*\");  \/\/ (2)<\/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  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"std::is_same&lt;int, int32_t&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int32_t<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_same&lt;int, int64_t&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int64_t<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_same&lt;long int, int64_t&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int64_t<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  \r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ static_assert(std::is_same&lt;int, int64_t&gt;::value,\"int is not the same type as int64_t\");              \/\/ (3)<\/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}<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The output of the program should not surprise you.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4990\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compare.png\" alt=\"compare\" width=\"500\" height=\"263\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compare.png 632w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compare-300x158.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>If I use the<code> static_assert<\/code> in lines (1), (2), and (3), the assertion fires at compile time:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4991\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compareStaticAssert.png\" alt=\"compareStaticAssert\" width=\"650\" height=\"217\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compareStaticAssert.png 856w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compareStaticAssert-300x100.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/compareStaticAssert-768x257.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>The website cppreference.com contains possible implementations of all the metafunctions <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_base_of\">std::is_base_of<\/a>,<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_same\"><code>std::is_convertible,<\/code>,<\/a> and <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_same\">std::is_same<\/a>. It&#8217;s pretty interesting and challenging to study them.&nbsp;<\/p>\n<\/p>\n<h3>Possible Implementations<\/h3>\n<p>First of all, here are possible implementations of the three metafunctions. Let me start with the simplest one, based on <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_same\">std::is_same<\/a>.<\/p>\n<h4><code>std::is_same<\/code><\/h4>\n<p>I use in the following example the namespace<code> rgr<\/code> to distinguish my implementation from the C++ standard implementation.<\/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;\">\/\/ isSame.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;\">namespace<\/span> rgr {\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span>, T v<span style=\"color: #555555;\">&gt;<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">struct<\/span> integral_constant {\r\n      <span style=\"color: #006699; font-weight: bold;\">static<\/span> constexpr T value <span style=\"color: #555555;\">=<\/span> v;\r\n      <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> T value_type;\r\n      <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> integral_constant type;\r\n      constexpr <span style=\"color: #006699; font-weight: bold;\">operator<\/span> value_type() <span style=\"color: #006699; font-weight: bold;\">const<\/span> noexcept { <span style=\"color: #006699; font-weight: bold;\">return<\/span> value; }\r\n      constexpr value_type <span style=\"color: #006699; font-weight: bold;\">operator<\/span>()() <span style=\"color: #006699; font-weight: bold;\">const<\/span> noexcept { <span style=\"color: #006699; font-weight: bold;\">return<\/span> value; } <span style=\"color: #0099ff; font-style: italic;\">\/\/since c++14<\/span>\r\n  };\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #336666;\">true<\/span><span style=\"color: #555555;\">&gt;<\/span> true_type;                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>              \r\n  <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #336666;\">false<\/span><span style=\"color: #555555;\">&gt;<\/span> false_type;\r\n  \r\n  <span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">U<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_same <span style=\"color: #555555;\">:<\/span> false_type {};                                       <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/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;\">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_same<span style=\"color: #555555;\">&lt;<\/span>T, T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">:<\/span> true_type {};\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> <span style=\"color: #cc3300;\">'\\n'<\/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;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"rgr::is_same&lt;int, const int&gt;::value: \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> rgr<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"rgr::is_same&lt;int, volatile int&gt;::value: \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> rgr<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #006699; font-weight: bold;\">volatile<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"rgr::is_same&lt;int, int&gt;::value: \"<\/span>  \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> rgr<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"std::is_same&lt;int, const int&gt;::value: \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_same&lt;int, volatile int&gt;::value: \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #006699; font-weight: bold;\">volatile<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_same&lt;int, int&gt;::value: \"<\/span>  \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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>&nbsp;A short reminder: The invocation of the function template<code>&nbsp;rgr::is_same&lt;int, const int&gt;<\/code> (line 1) causes the invocation of the expression <code>rgr::false_type::value<\/code> (line 2), because<code> std::is_same&lt;&gt;<\/code> is derived from <code>false_type<\/code> (line 3). <code>rgr::false_type::value<\/code> is an alias for <code>rgr::integral_constant&lt;bool, false&gt;::value<\/code> (line 2). I use in the example&nbsp;the static <code>constexpr<\/code> value of the class <code>integral_constant<\/code>.<code> integral_constant<\/code> is the base class of the type-traits functions.<\/p>\n<p>Two facts are interesting when you study the following output. My implementations<code> rgr::is_same<\/code> behaves such as <code>std::is_same<\/code>, and <code>const<\/code> and <code>volatile<\/code> are part of the type.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6167\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/06\/isSame.png\" alt=\"isSame\" width=\"500\" height=\"318\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>&nbsp;It&#8217;s pretty straightforward to implement the metafunction isSameIgnoringConstVolatile based on the metafunction is_same.<\/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;\">\/\/ isSameIgnoringConstVolatile.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;\">namespace<\/span> rgr {\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span>, T v<span style=\"color: #555555;\">&gt;<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">struct<\/span> integral_constant {\r\n      <span style=\"color: #006699; font-weight: bold;\">static<\/span> constexpr T value <span style=\"color: #555555;\">=<\/span> v;\r\n      <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> T value_type;\r\n      <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> integral_constant type;\r\n      constexpr <span style=\"color: #006699; font-weight: bold;\">operator<\/span> value_type() <span style=\"color: #006699; font-weight: bold;\">const<\/span> noexcept { <span style=\"color: #006699; font-weight: bold;\">return<\/span> value; }\r\n      constexpr value_type <span style=\"color: #006699; font-weight: bold;\">operator<\/span>()() <span style=\"color: #006699; font-weight: bold;\">const<\/span> noexcept { <span style=\"color: #006699; font-weight: bold;\">return<\/span> value; } <span style=\"color: #0099ff; font-style: italic;\">\/\/since c++14<\/span>\r\n  };\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #336666;\">true<\/span><span style=\"color: #555555;\">&gt;<\/span> true_type;                       \r\n  <span style=\"color: #006699; font-weight: bold;\">typedef<\/span> integral_constant<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">bool<\/span>, <span style=\"color: #336666;\">false<\/span><span style=\"color: #555555;\">&gt;<\/span> false_type;\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">U<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_same <span style=\"color: #555555;\">:<\/span> false_type {};\r\n \r\n  <span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_same<span style=\"color: #555555;\">&lt;<\/span>T, T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">:<\/span> true_type {};\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> U<span style=\"color: #555555;\">&gt;                                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">struct<\/span> isSameIgnoringConstVolatile<span style=\"color: #555555;\">:<\/span> rgr<span style=\"color: #555555;\">::<\/span>integral_constant<span style=\"color: #555555;\">&lt;<\/span>\r\n         <span style=\"color: #007788; font-weight: bold;\">bool<\/span>,\r\n         rgr<span style=\"color: #555555;\">::<\/span>is_same<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> std<span style=\"color: #555555;\">::<\/span>remove_cv<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>type, \r\n                      <span style=\"color: #006699; font-weight: bold;\">typename<\/span> std<span style=\"color: #555555;\">::<\/span>remove_cv<span style=\"color: #555555;\">&lt;<\/span>U<span style=\"color: #555555;\">&gt;::<\/span>type<span style=\"color: #555555;\">&gt;::<\/span>value  \r\n     <span style=\"color: #555555;\">&gt;<\/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> <span style=\"color: #cc3300;\">'\\n'<\/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;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"rgr::isSameIgnoringConstVolatile&lt;int, const int&gt;::value: \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> rgr<span style=\"color: #555555;\">::<\/span>isSameIgnoringConstVolatile<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"rgr::is_same&lt;int, volatile int&gt;::value: \"<\/span> \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> rgr<span style=\"color: #555555;\">::<\/span>isSameIgnoringConstVolatile<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #006699; font-weight: bold;\">volatile<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"rgr::isSameIgnoringConstVolatile&lt;int, int&gt;::value: \"<\/span>  \r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> rgr<span style=\"color: #555555;\">::<\/span>isSameIgnoringConstVolatile<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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 meta function<code> isSameIgnoringConstVolatile<\/code> derives from<code> rgr::integral_constant<\/code> and uses the function<code> std::remove_cv<\/code> to remove <code>const<\/code> or <code>volatile<\/code> from its types. As you may assume, <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/remove_cv\"><code>std::remove_cv<\/code><\/a> is a function from the type-traits library and allows you the modify types at compile time. I will write more about type modification in my next post.<\/p>\n<p>Finally, here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6254\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/isSameIgnoringConstVolatile.png\" alt=\"isSameIgnoringConstVolatile\" width=\"550\" height=\"216\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/isSameIgnoringConstVolatile.png 646w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/isSameIgnoringConstVolatile-300x118.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/p>\n<p>Let&#8217;s have a closer look at the two metafunctions <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_base_of\">std::is_base_of<\/a>, and <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_same\"><code>std::is_convertible<\/code><\/a><code>. <\/code>Here are the possible implementations from cppreference.com.<\/p>\n<h4><code>std::is_base_of<\/code><\/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;\">namespace<\/span> details {\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> B<span style=\"color: #555555;\">&gt;<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>true_type test_pre_ptr_convertible(<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">volatile<\/span> B<span style=\"color: #555555;\">*<\/span>);\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><span style=\"color: #555555;\">&gt;<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>false_type test_pre_ptr_convertible(<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">volatile<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span><span style=\"color: #555555;\">*<\/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>, <span style=\"color: #006699; font-weight: bold;\">typename<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> test_pre_is_base_of(...) <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>true_type;\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> B, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> D<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> test_pre_is_base_of(<span style=\"color: #007788; font-weight: bold;\">int<\/span>) <span style=\"color: #555555;\">-&gt;<\/span>\r\n        decltype(test_pre_ptr_convertible<span style=\"color: #555555;\">&lt;<\/span>B<span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #006699; font-weight: bold;\">static_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>D<span style=\"color: #555555;\">*&gt;<\/span>(nullptr)));\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> Base, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> Derived<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_base_of <span style=\"color: #555555;\">:<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>integral_constant<span style=\"color: #555555;\">&lt;<\/span>\r\n        <span style=\"color: #007788; font-weight: bold;\">bool<\/span>,\r\n        std<span style=\"color: #555555;\">::<\/span>is_class<span style=\"color: #555555;\">&lt;<\/span>Base<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span> std<span style=\"color: #555555;\">::<\/span>is_class<span style=\"color: #555555;\">&lt;<\/span>Derived<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n        decltype(details<span style=\"color: #555555;\">::<\/span>test_pre_is_base_of<span style=\"color: #555555;\">&lt;<\/span>Base, Derived<span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">0<\/span>))<span style=\"color: #555555;\">::<\/span>value\r\n    <span style=\"color: #555555;\">&gt;<\/span> { };\r\n<\/pre>\n<\/div>\n<h4><code>std::is_convertible<\/code><\/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;\">namespace<\/span> detail {\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> test_returnable(<span style=\"color: #007788; font-weight: bold;\">int<\/span>) <span style=\"color: #555555;\">-&gt;<\/span> decltype(\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span>(<span style=\"color: #006699; font-weight: bold;\">static_cast<\/span><span style=\"color: #555555;\">&lt;<\/span>T(<span style=\"color: #555555;\">*<\/span>)()<span style=\"color: #555555;\">&gt;<\/span>(nullptr)), std<span style=\"color: #555555;\">::<\/span>true_type{}\r\n);\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>class<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> test_returnable(...) <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>false_type;\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">From<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">To<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> test_implicitly_convertible(<span style=\"color: #007788; font-weight: bold;\">int<\/span>) <span style=\"color: #555555;\">-&gt;<\/span> decltype(\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span>(std<span style=\"color: #555555;\">::<\/span>declval<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">void<\/span>(<span style=\"color: #555555;\">&amp;<\/span>)(To)<span style=\"color: #555555;\">&gt;<\/span>()(std<span style=\"color: #555555;\">::<\/span>declval<span style=\"color: #555555;\">&lt;<\/span>From<span style=\"color: #555555;\">&gt;<\/span>())), std<span style=\"color: #555555;\">::<\/span>true_type{}\r\n);\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span>class, class<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> test_implicitly_convertible(...) <span style=\"color: #555555;\">-&gt;<\/span> std<span style=\"color: #555555;\">::<\/span>false_type;\r\n \r\n} <span style=\"color: #0099ff; font-style: italic;\">\/\/ namespace detail<\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">From<\/span>, <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">To<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> is_convertible <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    (decltype(detail<span style=\"color: #555555;\">::<\/span>test_returnable<span style=\"color: #555555;\">&lt;<\/span>To<span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">0<\/span>))<span style=\"color: #555555;\">::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span>\r\n     decltype(detail<span style=\"color: #555555;\">::<\/span>test_implicitly_convertible<span style=\"color: #555555;\">&lt;<\/span>From, To<span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">0<\/span>))<span style=\"color: #555555;\">::<\/span>value) <span style=\"color: #555555;\">||<\/span>\r\n    (std<span style=\"color: #555555;\">::<\/span>is_void<span style=\"color: #555555;\">&lt;<\/span>From<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&amp;&amp;<\/span> std<span style=\"color: #555555;\">::<\/span>is_void<span style=\"color: #555555;\">&lt;<\/span>To<span style=\"color: #555555;\">&gt;::<\/span>value)\r\n<span style=\"color: #555555;\">&gt;<\/span> {};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, you know why I explained<code> std::is_same<\/code>. Here is my challenge.<\/p>\n<h2>My Challenge<\/h2>\n<p>Explain the previous implementation of the type-traits functions<code> std::is_base_of<\/code> and<code> std::is_convertible<\/code>. Send your explanation to <a href=\"mailto:Rainer.Grimm@ModernesCpp.de&gt;\">Rainer.Grimm@ModernesCpp.de<\/a> until Thursday (December 2th). The best answer for each function gets a coupon for my LeanPub bundle <a href=\"https:\/\/leanpub.com\/b\/modernccollection\">Modern C++ Collection<\/a>.<\/p>\n<p><a href=\"https:\/\/leanpub.com\/b\/modernccollection\"><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6255\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/bundel.png\" alt=\"bundel\" width=\"493\" height=\"295\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/bundel.png 493w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/11\/bundel-300x180.png 300w\" sizes=\"auto, (max-width: 493px) 100vw, 493px\" \/><\/a>I will publish the best answer to each function in my next post and name your first name. If I should name your full name, please write it.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Thanks to the type-traits library, you can modify types at compile time. I write about it in my next post.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, &#8220;The Type-Traits Library: Type Checks&#8221; I introduced type checks at compile time with the type-traits library. Today, I write about type comparisons at compile time.<\/p>\n","protected":false},"author":21,"featured_media":6251,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[419],"class_list":["post-6256","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates","tag-type-traits"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6256","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=6256"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6256\/revisions"}],"predecessor-version":[{"id":6690,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6256\/revisions\/6690"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6251"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6256"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6256"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6256"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}