{"id":5198,"date":"2017-06-28T20:19:45","date_gmt":"2017-06-28T20:19:45","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=5198"},"modified":"2017-06-28T20:19:45","modified_gmt":"2017-06-28T20:19:45","slug":"revisiting-an-old-friend","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/revisiting-an-old-friend\/","title":{"rendered":"Revisiting an old friend"},"content":{"rendered":"<p><strong>Reminiscing<\/strong><\/p>\n<p>For many years (a long time ago in a galaxy far away) I was a C++ developer, but I haven&#8217;t done much in C++ for a while now, until recently&#8230;<\/p>\n<p>I needed to revisit a C++ application I wrote (not quite so long ago) to make a few additions and at the same time I thought it worth reviewing the changes that have taken place in C++ in recent years. This post is primarily looking at some of the changes as part of C++ 11 that I&#8217;ve come across whilst updating my app. and whilst not comprehensive, should give a taste for &#8220;Modern C++&#8221;.<\/p>\n<p><strong>auto is to C++ what var is to C#<\/strong><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nauto i = 1234;\r\n<\/pre>\n<p>This is resolved to the type at compile time (i.e. it&#8217;s not dynamic). The compiler simply resolves the type based upon the value on the right hand side of the assignment operator.<\/p>\n<p><strong>decltype<\/strong><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ntemplate&lt;typename A, typename B&gt;\r\nauto f(A a, B b) -&gt; decltype(a + b)\r\n{\r\n\treturn a + b;\r\n}\r\n<\/pre>\n<p>We can also use it in a sort of dynamic typedef manner<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\ndecltype(123) v = 1;\r\n\/\/ equivalent to \r\nint v = 1;\r\n<\/pre>\n<p>decltpye(123) declares the type as an int (as the type is taken from the argument passed in) then the value 1 is assigned to the variable. <\/p>\n<p><strong>for (each) loops known as range based loops in C++<\/strong><\/p>\n<p>The for loop (in a similar way to Java uses it) can be used as a foreach style loop. Although C++ calls this a range based loop. It only works on arrays or objects which have begin and end member functions (or initializer lists)<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nfor(auto &amp;it : myvector)\r\n{   \r\n}\r\n\r\n\/\/ using initializer list\r\n\r\nfor(auto i : { 1, 2, 3})\r\n{\r\n}\r\n<\/pre>\n<p><string>nullptr takes over from NULL<\/strong><\/p>\n<p>The nullptr is a strongly typed keyword which can replace those NULL or 0 usages when setting or testing a variable to see whether it points at something or not.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nif(errors == nullptr) \r\n{\r\n}\r\n<\/pre>\n<p>Another benefit of the keyword being strongly typed is that in situations when we might have two methods (with the name overloaded) one taking and int, the second a pointer type, then the compiler can now correctly choose the pointer overload, for example<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid f(int i)\r\n{\r\n}\r\n\r\nvoid f(int* i)\r\n{\r\n}\r\n\r\nf(NULL);    \/\/ calls f(int i)\r\nf(nullptr); \/\/ calls f(int* i)\r\n<\/pre>\n<p>So obviously the use of the NULL suggests the developer wants to use f(int*), but this is ambiguous and both could be correct. In the case of Visual Studio f(int) is called when we use NULL.<\/p>\n<p><strong>Lamda&#8217;s as well<\/strong><\/p>\n<p>I&#8217;ve written a longer post on lambda&#8217;s which will be published after this post. However, here&#8217;s a taster showing a lamda used within the algorithm header&#8217;s std::for_each function<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstd::for_each(v.begin(), v.end(), &#x5B;](int i)\r\n{\r\n   std::cout &lt;&lt; i;\r\n});\r\n<\/pre>\n<p><em>In this example, v is a vector of ints.<\/em><\/p>\n<p>The lambda is denoted with the [] which captures variables from the calling code (in this case nothing is captured) and the rest is probably self-explanatory, we&#8217;ve created a lambda which takes and int and uses cout to write the value to the console. <\/p>\n<p><strong>Initializer lists<\/strong><\/p>\n<p>Like C# we can create lists using { } syntax, for example<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstd::array&lt;int, 3&gt; a = { 1, 2, 3 };\r\n\/\/ or using a vector\r\nstd::vector&lt;int&gt; v = { 1, 2, 3 };\r\n<\/pre>\n<p><em>Sadly, Visual Studio 2015 doesn&#8217;t appear to fully support this syntax and allow us to easily intialize vectors etc. but CLion does. But thankfully Visual Studio 2017 does support this fully.<\/p>\n<p>Note: Visual Studio 2015 accepts using <em>std::vector<int> v = { 3, (1,2,3) };<\/em> where the first number is the size of the vector.<br \/>\n<\/em><\/p>\n<p><strong>Non-static member initializers<\/strong><\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nclass FileData\r\n{\r\npublic:\r\n   long a {0};\r\n   long b {1};\r\n}\r\n<\/pre>\n<p>Upon creation of a FileData instance, <em>a<\/em> is initialized to 0 and <em>b<\/em> is initialized to 1.<\/p>\n<p><strong>Tuples<\/strong><\/p>\n<p>We can now create tuples by include the tuple header and creating a tuple using the <em>std::make_tuple<\/em> function, i.e. <\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nauto t = std::make_tuple&lt;int, std::string&gt;(123, &quot;Hello&quot;);\r\n<\/pre>\n<p>To get at each part of the tuple we can use either the get function or the tie function, like this<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstd::cout \r\n   &lt;&lt; std::get&lt;0&gt;(t) \r\n   &lt;&lt; std::get&lt;1&gt;(t) \r\n   &lt;&lt; std::endl;\r\n<\/pre>\n<p>Note: the index goes in the template argument.<\/p>\n<p>Or using tie<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nint a;\r\nstd::string b;\r\n\r\nstd::tie(a, b) = t;\r\n\r\nstd::cout \r\n   &lt;&lt; a \r\n   &lt;&lt; b \r\n   &lt;&lt; std::endl;\r\n<\/pre>\n<p><strong>std::thread, yes threads made easier<\/strong><\/p>\n<p>Okay, we&#8217;re not talking Task or async\/await capabilities like C# but the std::thread class makes C++ threading that bit easier.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;thread&gt;\r\n#include &lt;iostream&gt;\r\n\r\nvoid f(std::string s, int n) {\r\n   for (int i = 0; i &lt; n; i++)\r\n      std::cout &lt;&lt; s.c_str() &lt;&lt; std::endl;\r\n}\r\nint main()\r\n{\r\n   std::thread thread1(f, &quot;Hello&quot;, 10);\r\n   std::thread thread2(f, &quot;World&quot;, 3);\r\n\t\r\n   thread1.join();\r\n   thread2.join();\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<p>In this code we create a thread passing in the function and the arguments for the function, using join to wait until both threads have completed.<\/p>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/AnthonyCalandra\/modern-cpp-features#tuples\" target=\"_blank\">Modern C+ Features<\/a><br \/>\n<a href=\"https:\/\/msdn.microsoft.com\/en-gb\/library\/hh567368.aspx\" target=\"_blank\">Support For C++11\/14\/17 Features (Modern C++)<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Reminiscing For many years (a long time ago in a galaxy far away) I was a C++ developer, but I haven&#8217;t done much in C++ for a while now, until recently&#8230; I needed to revisit a C++ application I wrote (not quite so long ago) to make a few additions and at the same time [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[180],"tags":[],"class_list":["post-5198","post","type-post","status-publish","format-standard","hentry","category-cc"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5198","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=5198"}],"version-history":[{"count":11,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5198\/revisions"}],"predecessor-version":[{"id":5215,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5198\/revisions\/5215"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=5198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=5198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=5198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}