{"id":5233,"date":"2017-04-04T20:44:13","date_gmt":"2017-04-04T20:44:13","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-17-more-details-to-the-core-language\/"},"modified":"2017-04-04T20:44:13","modified_gmt":"2017-04-04T20:44:13","slug":"c-17-more-details-to-the-core-language","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-17-more-details-to-the-core-language\/","title":{"rendered":"C++17- More Details about the Core Language"},"content":{"rendered":"<p>After I provided the big picture of the new C++17 core language in my post &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/cpp17-core\">C++17 &#8211; What&#8217;s New in the Core Language<\/a>&#8220;, I will give you more details today. The details are mainly about inline variables, templates, automatic type deduction with<span style=\"font-family: courier new,courier;\"> auto,<\/span> and attributes.<\/p>\n<p><!--more--><\/p>\n<p>Here is the big picture of C++17 once more.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4724\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/04\/timeline.png\" alt=\"timeline\" width=\"700\" height=\"338\" style=\"margin: 15px auto; display: block;\" \/><\/p>\n<p>But let me write about the not-so-well-known feature.<\/p>\n<h2>Inline variables<\/h2>\n<p>Thanks to <span style=\"font-family: courier new,courier;\">inline<\/span> variables, the main reason for not packaging C++ code as header-only libraries are gone. You can declare global variables and static variables <span style=\"font-family: courier new,courier;\">inline.<\/span> The same rules applied to <span style=\"font-family: courier new,courier;\">inline<\/span> functions are applied to <span style=\"font-family: courier new,courier;\">inline<\/span> variables.<\/p>\n<p>That means:<\/p>\n<ul>\n<li>There can be more than one definition of an <span style=\"font-family: courier new,courier;\">inline<\/span> variable.<\/li>\n<li>The definition of an <span style=\"font-family: courier new,courier;\">inline<\/span> variable must be present in the translation unit in which it is used.<\/li>\n<li>A global <span style=\"font-family: courier new,courier;\">inline<\/span> variable (non-static <span style=\"font-family: courier new,courier;\">inline<\/span> variable) must be declared <span style=\"font-family: courier new,courier;\">inline<\/span> in every translation unit and has the same address in every translation unit.<\/li>\n<\/ul>\n<p>Once more, the great benefit of <span style=\"font-family: courier new,courier;\">inline<\/span> variables. You can put your variables directly into your header files and include them more than once.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ widget.h<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">Widget<\/span>{\r\n  public:\r\n    Widget() = <span style=\"color: #0000ff;\">default<\/span>;\r\n    Widget(<span style=\"color: #2b91af;\">int<\/span> w): width(w), height(getHeight(w)){}\r\n    Widget(<span style=\"color: #2b91af;\">int<\/span> w, <span style=\"color: #2b91af;\">int<\/span> h): width(w), height(h){}\r\n\r\n  private:\r\n    <span style=\"color: #2b91af;\">int<\/span> getHeight(<span style=\"color: #2b91af;\">int<\/span> w){ <span style=\"color: #0000ff;\">return<\/span> w*3\/4; }\r\n    <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">int<\/span> width= 640;\r\n    <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">int<\/span> height= 480;\r\n    <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">bool<\/span> frame= false;\r\n    <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">bool<\/span> visible= true;\r\n\r\n    ...\r\n};\r\n\r\n<span style=\"color: #0000ff;\">inline<\/span> Widget wVGA;\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">auto<\/span> can automatically deduce the type of its variable from its initializer. The story with <span style=\"font-family: courier new,courier;\">auto<\/span> goes on. Thanks to <span style=\"font-family: courier new,courier;\">auto,<\/span> template parameters of function templates and constructors (see <a href=\"https:\/\/www.modernescpp.com\/index.php\/cpp17-core\">C++17 &#8211; What&#8217;s New in the Core Language<\/a>) can automatically be deduced from its arguments, and non-type template parameters can automatically be deduced from its template arguments. Irritated about the last part of my sentence? Irritated? That&#8217;s fine. I will write about the last part of my sentence in the next chapter.<\/p>\n<\/p>\n<h2>Automatic type deduction of non-type template parameters<\/h2>\n<p>First of all. What are non-type template parameters? These are nullptr, integral, lvalue reference, pointer, and enumeration types. I will refer in this post mainly to integral types.<\/p>\n<p>After so much theory, let&#8217;s start with an example.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">auto<\/span> N&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyClass<\/span>{\r\n  ...\r\n};\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #2b91af;\">int<\/span> N&gt; \r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyClass<\/span>&lt;N&gt; {\r\n  ...\r\n};\r\n\r\n\r\nMyClass&lt;<span style=\"color: #a31515;\">'x'<\/span>&gt; myClass2;     <span style=\"color: #008000;\">\/\/ Primary template for char<\/span>\r\nMyClass&lt;2017&gt;  myClass1;   <span style=\"color: #008000;\">\/\/ Partial specialisation for int<\/span>\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>By using <span style=\"font-family: courier new,courier;\">auto<\/span> in line 1 in the template signature,&nbsp; <span style=\"font-family: courier new,courier;\">N<\/span> is a non-type template parameter. The compiler will automatically deduce it. A partial specialization for <span style=\"font-family: courier new,courier;\">int<\/span> is also possible: lines 6 and 7. The template instantiation in line 12 will use the primary template (lines 1-4), and the following template instantiation is the partial specialization for<span style=\"font-family: courier new,courier;\"> int.<\/span><\/p>\n<p>The usual type modifiers can be used to constrain the type of the non-type template parameters. Therefore, you don&#8217;t have to use partial specialization.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre class=\"example\"><span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">auto<\/span>* p&gt; \r\n<span style=\"color: #0000ff;\">struct<\/span> S;\r\n<code class=\"prettyprint\"><em><\/em><span style=\"font-family: courier new,courier;\"><br \/><\/span><\/code><\/pre>\n<\/div>\n<p>Here, <span style=\"font-family: courier new,courier;\">p<\/span> must be a pointer to <span style=\"font-family: courier new,courier;\">const.<\/span><\/p>\n<p>The automatic type deduction for non-type template parameters works even for variadic templates.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\">1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">auto<\/span>... ns&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">VariadicTemplate<\/span>{\r\n  ...\r\n};\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">auto<\/span> n1, decltype(n1)... ns&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">TypedVariadicTemplate<\/span>{\r\n  ...\r\n};\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Therefore, <span style=\"font-family: courier new,courier;\">VariadicTemplate<\/span> in lines 1-4 can deduce an arbitrary number of non-type template parameters. <span style=\"font-family: courier new,courier;\">TypeVariadicTemplate<\/span> will deduce only the first template parameter. The remaining templated parameters will be of the same type.<\/p>\n<p>The rules for auto in combination with a {}-Initialisation change in C++17.<\/p>\n<h2>auto in combination with an {}-Initialisation<\/h2>\n<p>Combining auto with an {}-Initialisation will give you a <span style=\"font-family: courier new,courier;\">std::initializer_list<\/span>.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\">  <span style=\"color: #0000ff;\">auto<\/span> initA{1};          <span style=\"color: #008000;\">\/\/ std::initializer_list&lt;int&gt;<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> initB= {2};        <span style=\"color: #008000;\">\/\/ std::initializer_list&lt;int&gt;<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> initC{1, 2};       <span style=\"color: #008000;\">\/\/ std::initializer_list&lt;int&gt;<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> initD= {1, 2};     <span style=\"color: #008000;\">\/\/ std::initializer_list&lt;int&gt;<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>That was an easy-to-remember and to-teach rule. Sad to say; however, C++17 makes the feature from my perspective not better.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\">  <span style=\"color: #0000ff;\">auto<\/span> initA{1};          <span style=\"color: #008000;\">\/\/ int<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> initB= {2};        <span style=\"color: #008000;\">\/\/ std::initializer_list&lt;int&gt;<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> initC{1, 2};       <span style=\"color: #008000;\">\/\/ error, no single element<\/span>\r\n  <span style=\"color: #0000ff;\">auto<\/span> initD= {1, 2};     <span style=\"color: #008000;\">\/\/ std::initializer_list&lt;int&gt;<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the rule is more complicated. Assigning with a {} returns a <span style=\"font-family: courier new,courier;\">std::initializer_list. <\/span>Copy construction only works for a single value.<span style=\"font-family: courier new,courier;\"> <\/span><\/p>\n<p>Now to a small but nice feature.<\/p>\n<h2>Nested namespaces<\/h2>\n<p>With C++17, you can quite comfortably define nested namespaces.<\/p>\n<p>Instead of writing<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">namespace<\/span> A {\r\n  <span style=\"color: #0000ff;\">namespace<\/span> B {\r\n    <span style=\"color: #0000ff;\">namespace<\/span> C {\r\n      ...\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>you can simply write:<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">namespace<\/span> A::B::C {\r\n  ...\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>C++17 has the three new attributes<span style=\"font-family: courier new,courier;\"> [[fallthrough]], [[nodiscard]]<\/span>, and <span style=\"font-family: courier new,courier;\">[[maybe_unused]]. <\/span><\/p>\n<h2>The three new attributes fallthrough, nodiscard, and maybe_unused<\/h2>\n<p>All three deal with compiler warnings. The examples are from <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/attributes\">cppreference.com<\/a>.<\/p>\n<h3>fallthrough<\/h3>\n<p><span style=\"font-family: Courier New,Courier,monospace;\">[[fallthrough]]<\/span> can be used in a <span style=\"font-family: courier new,courier;\">switch<\/span> statement. It has to be on its own line, immediately before a <span style=\"font-family: courier new,courier;\">case<\/span> label, indicating that a fall-through is intentional and should not diagnose a compiler warning.<\/p>\n<p>Here is a small example.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #2b91af;\">void<\/span> f(<span style=\"color: #2b91af;\">int<\/span> n) {\r\n  <span style=\"color: #2b91af;\">void<\/span> g(), h(), i();\r\n  <span style=\"color: #0000ff;\">switch<\/span> (n) {\r\n    <span style=\"color: #0000ff;\">case<\/span> 1:\r\n    <span style=\"color: #0000ff;\">case<\/span> 2:\r\n      g();\r\n     [[fallthrough]];\r\n    <span style=\"color: #0000ff;\">case<\/span> 3: <span style=\"color: #008000;\">\/\/ no warning on fallthrough<\/span>\r\n      h();\r\n    <span style=\"color: #0000ff;\">case<\/span> 4: <span style=\"color: #008000;\">\/\/ compiler may warn on fallthrough<\/span>\r\n      i();\r\n      [[fallthrough]]; <span style=\"color: #008000;\">\/\/ ill&shy;formed, not before a case label<\/span>\r\n  }\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The<span style=\"font-family: courier new,courier;\"> [[fallthrough]]<\/span> attribute in line 7 suppresses a compiler warning. That will not hold for line 10. The compiler may warn. Line 12 is ill-formed because no <span style=\"font-family: courier new,courier;\">case<\/span> label is following.<\/p>\n<h3>nodiscard<\/h3>\n<p><span style=\"font-family: Courier New,Courier,monospace;\">[[nodiscard]] <\/span>can be used in a function, enumeration, or class declaration. If you discard the return value from a function declared as nodiscard, the compiler should issue a warning. The same holds for a function returning an enumeration or a class, declared as nodiscard. A cast-to-void should not emit a warning.<\/p>\n<p>Therefore, line 5 should emit a warning, but line 10 should not produce a warning because the function <span style=\"font-family: Courier New,Courier,monospace;\">foo <\/span>returns by reference.<\/p>\n<div style=\"background: #ffffff none repeat scroll 0% 0%; overflow: auto; width: auto; border-width: 0.1em 0.1em 0.1em 0.8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0000ff;\">struct<\/span> [[nodiscard]] error_info { };\r\nerror_info enable_missile_safety_mode();\r\n<span style=\"color: #2b91af;\">void<\/span> launch_missiles();\r\n<span style=\"color: #2b91af;\">void<\/span> test_missiles() {\r\n   enable_missile_safety_mode(); <span style=\"color: #008000;\">\/\/ compiler may warn on discarding a nodiscard value<\/span>\r\n   launch_missiles();\r\n}\r\nerror_info&amp; foo();\r\n<span style=\"color: #2b91af;\">void<\/span> f1() {\r\n    foo(); <span style=\"color: #008000;\">\/\/ nodiscard type is not returned by value, no warning<\/span>\r\n} \r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3>maybe_unused<\/h3>\n<p><span style=\"font-family: Courier New,Courier,monospace;\">[[maybe_unused]]<\/span> can be used to declare a class, a typedef&shy;, a variable, a non&shy;-static data member, a function, an enumeration, or an enumerator. Thanks to maybe_unused, the compiler suppresses a warning on an unused entity.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\">1\r\n2\r\n3\r\n4\r\n5\r\n6<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #2b91af;\">void<\/span> f([[maybe_unused]] <span style=\"color: #2b91af;\">bool<\/span> thing1,\r\n       [[maybe_unused]] <span style=\"color: #2b91af;\">bool<\/span> thing2)\r\n{\r\n   [[maybe_unused]] <span style=\"color: #2b91af;\">bool<\/span> b = thing1;\r\n   assert(b); <span style=\"color: #008000;\">\/\/ in release mode, assert is compiled out<\/span>\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In release mode, line 5 is compiled out. That should produce no warning because<span style=\"font-family: courier new,courier;\"> b<\/span><span id=\"transmark\"><\/span> is declared as maybe_unused. The same holds for the variable <span style=\"font-family: courier new,courier;\">thing2.<\/span><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>After my introduction to the core C++17 language ( <a href=\"https:\/\/www.modernescpp.com\/index.php\/cpp17-core\">C++17 &#8211; What&#8217;s New in the Core Language<\/a>), I gave you more in this post more details. The same will hold for my next post. I will present in my next post more details to the new C++17 library. So, in case <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-17-what-s-new-in-the-library\">C++17 &#8211; What\u00b4s New in the Library<\/a> made you curious.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>After I provided the big picture of the new C++17 core language in my post &#8220;C++17 &#8211; What&#8217;s New in the Core Language&#8220;, I will give you more details today. The details are mainly about inline variables, templates, automatic type deduction with auto, and attributes.<\/p>\n","protected":false},"author":21,"featured_media":4724,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[370],"tags":[],"class_list":["post-5233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-17"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5233","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=5233"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5233\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4724"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}