{"id":1788,"date":"2018-07-06T11:50:48","date_gmt":"2018-07-06T10:50:48","guid":{"rendered":"http:\/\/www.nuonsoft.com\/blog\/?p=1788"},"modified":"2018-07-06T11:50:48","modified_gmt":"2018-07-06T10:50:48","slug":"const-auto-versus-const-auto-for-pointer-types","status":"publish","type":"post","link":"https:\/\/www.nuonsoft.com\/blog\/2018\/07\/06\/const-auto-versus-const-auto-for-pointer-types\/","title":{"rendered":"const auto* versus const auto for Pointer Types"},"content":{"rendered":"<p>When working with references, C++ developers have been trained to use <strong>auto&amp;<\/strong>, <strong>const auto&amp;<\/strong>, or <strong>auto&amp;&amp;<\/strong> to avoid copies being made. However, when dealing with pointers, developers often do not use <strong>auto*<\/strong> but simply use <strong>auto<\/strong> instead. With pointers, there is no danger that you make accidental copies of the data, but there are other issues with omitting the <strong>*<\/strong>. Also, when working with pointers, there is a big difference between using <strong>const auto<\/strong> versus <strong>const auto*<\/strong>.<\/p>\n<p>Let&#8217;s assume you have the following simple classes:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">#include &lt;memory&gt;\r\n\r\nclass Data {};\r\n\r\nclass Foo\r\n{\r\npublic:\r\n\tFoo() : m_data(std::make_unique&lt;Data&gt;()) { }\r\n\r\n\tData* GetData() { return m_data.get(); }\r\n\r\nprivate:\r\n\tstd::unique_ptr&lt;Data&gt; m_data;\r\n};<\/pre>\n<p>The <strong>GetData()<\/strong> method simply returns a pointer to a <strong>Data<\/strong> instance.<\/p>\n<p>When using <strong>auto,<\/strong> a lot of developers simply write the following:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">Foo foo;\r\nauto d1 = foo.GetData();\r\n<\/pre>\n<p>The resulting type of <strong>d1<\/strong> is<strong> Data*<\/strong>.<\/p>\n<p>I actually recommend to write the following instead:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">auto* d2 = foo.GetData();<\/pre>\n<p><strong>d2<\/strong> is also of type <strong>Data*<\/strong>, but the benefit is that you immediately see that you are dealing with a pointer. I know, in most IDE&#8217;s you can simply hover your mouse over the variable name and it will tell you the exact type. However, sometimes you are not working in an IDE. One such example is when doing code review in an external tool. Most of these tools do not show you that information when hovering over the name of a variable. This makes it a bit more difficult during code review to know that <strong>d2<\/strong> is actually a pointer. When you write <strong>auto*<\/strong>, then it&#8217;s immediately obvious.<\/p>\n<p>Now, let&#8217;s throw <strong>const<\/strong> into the mix. Again, most developers will not write the <strong>*<\/strong> with <strong>auto,<\/strong> so they write the following:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">const auto d3 = foo.GetData();<\/pre>\n<p>However, this is most of the time not doing what you expect it to do!<br \/>\nOften, when you use <strong>const,<\/strong> you want to protect the thing to which the pointer is pointing to. A lot of developers assume that <strong>d3<\/strong> is of type <strong>const Data*<\/strong>, but in fact, the type is <strong>Data* const<\/strong>, so it&#8217;s a <strong>const<\/strong> pointer to a non-<strong>const Data!<\/strong> Putting the <strong>const<\/strong> after the <strong>auto<\/strong> as follows doesn&#8217;t help, the type is still <strong>Data* const<\/strong>:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">auto const d4 = foo.GetData();<\/pre>\n<p>When you use <strong>auto*<\/strong> in combination with <strong>const,<\/strong> then it&#8217;s behaving as you would expect. For example:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">const auto* d5 = foo.GetData();<\/pre>\n<p>With this line, <strong>d5<\/strong> is of type <strong>const Data*<\/strong> \ud83d\ude42<\/p>\n<p>If you really want a <strong>const<\/strong> pointer instead of <strong>const<\/strong> data, you put the <strong>const<\/strong> at the end:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">auto* const d6 = foo.GetData();<\/pre>\n<p><strong>d6<\/strong> has type <strong>Data* const.<\/strong><\/p>\n<p>And finally, with this syntax you can make both the pointer and the data constant:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">const auto* const d7 = foo.GetData();<\/pre>\n<p><strong>d7<\/strong> is of type <strong>const Data* const<\/strong>. You cannot achieve this if you omit the <strong>*<\/strong>.<\/p>\n<p>All this is something to keep in mind. I&#8217;ve seen developers make mistakes against this several times.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When working with references, C++ developers have been trained to use auto&amp;, const auto&amp;, or auto&amp;&amp; to avoid copies being made. However, when dealing with pointers, developers often do not use auto* but simply use auto instead. With pointers, there is no danger that you make accidental copies of the data, but there are other [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[44,232],"class_list":["post-1788","post","type-post","status-publish","format-standard","hentry","category-c","tag-auto","tag-const"],"_links":{"self":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1788","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=1788"}],"version-history":[{"count":10,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1788\/revisions"}],"predecessor-version":[{"id":1798,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1788\/revisions\/1798"}],"wp:attachment":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=1788"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/categories?post=1788"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/tags?post=1788"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}