{"id":5614,"date":"2019-01-17T20:54:10","date_gmt":"2019-01-17T20:54:10","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-programming-at-compile-time-with-the-type-traits\/"},"modified":"2023-06-26T10:15:56","modified_gmt":"2023-06-26T10:15:56","slug":"c-core-guidelines-programming-at-compile-time-with-the-type-traits","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-programming-at-compile-time-with-the-type-traits\/","title":{"rendered":"C++ Core Guidelines: Programming at Compile Time with the Type-Traits"},"content":{"rendered":"<p>My journey through programming at compile time began in the last posts with template metaprogramming. Today, I jumped from C++98 to C++11. This is a jump to the type-traits library which is template metaprogramming in a standardized way.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5613\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/TypeTraits.PNG\" alt=\"TypeTraits\" width=\"500\" height=\"383\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/TypeTraits.PNG 744w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/01\/TypeTraits-300x230.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>The<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\"> type-traits library<\/a> has been part of C++ since C++11. Its origin is in <a href=\"https:\/\/www.boost.org\/\">boost<\/a>. The type traits support type checks, comparisons, and type modifications at compile time. The library has over 100 functions, but each C++ standard adds new ones.<\/p>\n<p>I will not go into the details of the type-traits library because I have already written posts about it: <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/type-traits\">type-traits library<\/a>. On the contrary, I cannot skip the type-traits library to continue my introduction to programming at compile time. In the end, here is my short introduction to the type-traits library. For more information, I add links to my older posts.<\/p>\n<p>First of all, what&#8217;s inside the type-traits library?<\/p>\n<\/p>\n<h2>The Type-Traits Library<\/h2>\n<p>The library consists of type checks, type comparisons, and type modifications. Let me start with the type checks.<\/p>\n<h3>Type Checks<\/h3>\n<p>Each type belongs precisely to one primary type category.<\/p>\n<h4>Primary type categories<\/h4>\n<p>Here are they:<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_void;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_integral;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_floating_point;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_array;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_pointer;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_null_pointer;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_member_object_pointer;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_member_function_pointer;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_enum;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_union;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_class;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_function;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_lvalue_reference;\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_rvalue_reference;<br \/><br \/><br \/><br \/><\/pre>\n<\/div>\n<p>The following program gives you each primary type category a type.<\/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;\">\/\/  primaryTypeCategories.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;\">struct<\/span> A{\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> a;\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">f<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span>){<span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">2011<\/span>;}\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">enum<\/span> E{\r\n  e<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>,\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">union<\/span> U{\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> u;\r\n};\r\n\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span>  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> std<span style=\"color: #555555;\">::<\/span>is_void<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">void<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">short<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_floating_point<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> []<span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_pointer<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_null_pointer<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">std::nullptr_t<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_member_object_pointer<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> A<span style=\"color: #555555;\">::*&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_member_function_pointer<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> (A<span style=\"color: #555555;\">::*<\/span>)(<span style=\"color: #007788; font-weight: bold;\">int<\/span>)<span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_enum<span style=\"color: #555555;\">&lt;<\/span>E<span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_union<span style=\"color: #555555;\">&lt;<\/span>U<span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_class<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_function<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #555555;\">*<\/span> (<span style=\"color: #007788; font-weight: bold;\">double<\/span>)<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\t\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>is_lvalue_reference<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;&gt;::<\/span>value <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> std<span style=\"color: #555555;\">::<\/span>is_rvalue_reference<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&amp;&amp;&gt;::<\/span>value <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>Here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4986\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/primaryTypeCategories.png\" alt=\"primaryTypeCategories\" width=\"500\" height=\"351\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/primaryTypeCategories.png 543w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/primaryTypeCategories-300x210.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>If you want to know how this magic works, my post <a href=\"https:\/\/www.modernescpp.com\/index.php\/check-types\">Check Types<\/a> provides more information.<\/p>\n<p>Based on the primary type categories are the composite type categories.<\/p>\n<h4>Composite Type Categories<\/h4>\n<p>The following table shows the relation between the primary type categories and the composite type categories.&nbsp;<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4988\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/CompositeTypeCategories.png\" alt=\"CompositeTypeCategories\" width=\"500\" height=\"383\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/CompositeTypeCategories.png 915w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/CompositeTypeCategories-300x229.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/10\/CompositeTypeCategories-768x587.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>There are more type checks possible with the type traits.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\"><\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">    template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_const;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_volatile;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivial;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_copyable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_standard_layout;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_pod;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_literal_type;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_empty;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_polymorphic;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_abstract;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_signed;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_unsigned;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>, class... Args&gt; <span style=\"color: #0000ff;\">struct<\/span> is_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_default_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_copy_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_move_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>, <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">U<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_copy_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_move_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_destructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>, class... Args&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_default_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_copy_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_move_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>, <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">U<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_copy_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_move_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_trivially_destructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>, class... Args&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_default_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_copy_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_move_constructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>, <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">U<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_copy_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_move_assignable;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> is_nothrow_destructible;<br \/>    <span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">T<\/span>&gt; <span style=\"color: #0000ff;\">struct<\/span> has_virtual_destructor;<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Many of the function templates like<span style=\"font-family: courier new, courier;\"> is_trivially_copyable<\/span> have the name component <span style=\"font-family: courier new, courier;\">trivially.<\/span> That means that these methods are not implemented by you but by the compiler.&nbsp; Requesting a method from the compiler with the keyword <span style=\"font-family: courier new,courier;\">default<\/span> is also trivial.<\/p>\n<h3>Type Comparisons<\/h3>\n<p>The type-traits library supports 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><span style=\"font-family: courier new, courier;\"><\/span><\/li>\n<\/ul>\n<p>The following example uses all three functions<\/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;\">\/\/ 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> 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;\">\"std::is_base_of&lt;Base, Derived&gt;::value: \"<\/span> \r\n            <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> 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;\">\"std::is_base_of&lt;Derived, Base&gt;::value: \"<\/span> \r\n            <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> 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;\">\"std::is_base_of&lt;Derived, Derived&gt;::value: \"<\/span> \r\n            <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> 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  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> \r\n            <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> 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;\">\"std::is_convertible&lt;Derived*, Base*&gt;::value: \"<\/span> \r\n            <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> 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;\">\"std::is_convertible&lt;Derived*, Derived*&gt;::value: \"<\/span> \r\n            <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> 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  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> \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;\">int32_t<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_same&lt;int, int64_t&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;\">int64_t<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <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;\">\"std::is_same&lt;long int, int64_t&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;\">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> 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>and has the expected outcome.<\/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=\"600\" height=\"317\" 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: 600px) 100vw, 600px\" \/><\/p>\n<h2>Programming At Compile Time<\/h2>\n<p>Okay, let&#8217;s step back and think about the functions of the type-traits library. Here are a few observations.<\/p>\n<ul>\n<li>The functions from the type-traits library are metafunctions because they run at compile time. Metafunctions are class templates<\/li>\n<li>The metafunctions&#8217; arguments that go into the sharp brackets (<span style=\"font-family: courier new, courier;\">&lt;&#8230;&gt;<\/span>) are metadata. Metadata are (in this case) types.<\/li>\n<li>The return value of the functions is the (<span style=\"font-family: courier new, courier;\">::value<\/span>). This is just an alias. Since C++17, there is a more straightforward form for getting the result: instead of <span style=\"font-family: courier new, courier;\">std::is_void&lt;void&gt;::value,<\/span> you type<span style=\"font-family: courier new, courier;\"> std::is_void_v&lt;void&gt;<\/span>.<\/li>\n<\/ul>\n<p>I hope these three observations remind you of my last post. These are precisely the conventions I presented in my previous post to template metaprogramming: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-programming-at-compile-time\">C++ Core Guidelines: Programming at Compile Time<\/a>.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>If a function from the type-traits library wants to return a type, not a value, you must ask for it with <span style=\"font-family: courier new, courier;\">::type.<\/span>&nbsp; My following post shows which type of modifications the type-traits library supports at compile time. Ultimately, the type-traits library has two goals: correctness and optimization.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My journey through programming at compile time began in the last posts with template metaprogramming. Today, I jumped from C++98 to C++11. This is a jump to the type-traits library which is template metaprogramming in a standardized way.<\/p>\n","protected":false},"author":21,"featured_media":5613,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[435,419],"class_list":["post-5614","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-template-metaprogramming","tag-type-traits"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5614","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=5614"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5614\/revisions"}],"predecessor-version":[{"id":6798,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5614\/revisions\/6798"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5613"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5614"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5614"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5614"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}