{"id":5652,"date":"2019-03-13T20:17:42","date_gmt":"2019-03-13T20:17:42","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-insights-conversions\/"},"modified":"2023-06-26T10:13:42","modified_gmt":"2023-06-26T10:13:42","slug":"c-insights-conversions","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-insights-conversions\/","title":{"rendered":"C++ Insights &#8211; Implicit Conversions"},"content":{"rendered":"<p>I&#8217;m totally happy to announce that this post starts a series of posts to <a href=\"https:\/\/cppinsights.io\/\">C++ Insights<\/a>. C++ Insights is an awesome tool that I use heavily in my posts and in my classes to show the magic of the C++ compiler.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5651\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/01-implicit-conversions.png\" alt=\"01 implicit conversions\" width=\"700\" height=\"394\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/01-implicit-conversions.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/01-implicit-conversions-300x169.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/01-implicit-conversions-1024x576.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/01-implicit-conversions-768x432.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>This series is motivated by a brief conversation I had with <a href=\"https:\/\/www.andreasfertig.blog\/2019\/03\/hello-cpp-insights.html\">Andreas<\/a>. I asked him if he has some use case examples which show how <a href=\"https:\/\/cppinsights.io\">C++ Insights<\/a> can be helpful when teaching. I think there are many things. This article is the start of a series of five posts by Andreas which I will publish at Modernes C++ because I think C++ Insights is an invaluable tool to get a deeper insight into the C++ compiler magic. In case, you are new to C++ Insights consider <a href=\"https:\/\/andreasfertig.blog\/2019\/03\/hello-cpp-insights\/\">this introductory article<\/a>. Without further ado, Andreas post. When you follow the link near to each example, you can directly analyse the example in C++ Insight.<\/p>\n<h2>Implicit Conversions<\/h2>\n<p>Let\u2019s start with something simple which happens so often: implicit conversations. Sometimes, they are perceived as cumbersome or hidden, sometimes as powerful. For beginners and even for experts in certain debugging situations it is hard to see where implicit conversations happen.<\/p>\n<h3>A Basic Example<\/h3>\n<p>Consider this basic <a href=\"https:\/\/cppinsights.io\/lnk?code=dm9pZCBVbnNpZ25lZEludEZ1bmN0aW9uKHVuc2lnbmVkIGludCkge30KCmludCBtYWluKCkKewogIGludCB4ID0gMTsKICBVbnNpZ25lZEludEZ1bmN0aW9uKHgpOwp9&amp;rev=1.0\">example<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">UnsignedIntFunction<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">unsigned<\/span> <span class=\"hljs-keyword\">int<\/span>)<\/span> <\/span>{}\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-keyword\">int<\/span> x = <span class=\"hljs-number\">1<\/span>;\r\n    UnsignedIntFunction(x);\r\n}\r\n<\/code><\/pre>\n<p>With these few lines and knowledge of C++, it is easy to see that <code>UnsignedIntFunction<\/code> takes a <code>unsigned int<\/code> while we are passing an <code>int<\/code>. Aside from the fact that the two types have different ranges on the call side, it works without additional work. This truncation is harder to spot in a bigger codebase. For students, it is even harder in my experience. Using C++ Insights gives you the following output:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">UnsignedIntFunction<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">unsigned<\/span> <span class=\"hljs-keyword\">int<\/span>)<\/span>\r\n<\/span>{\r\n}\r\n\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  <span class=\"hljs-keyword\">int<\/span> x = <span class=\"hljs-number\">1<\/span>;\r\n  UnsignedIntFunction(<span class=\"hljs-keyword\">static_cast<\/span>&lt;<span class=\"hljs-keyword\">unsigned<\/span> <span class=\"hljs-keyword\">int<\/span>&gt;(x));\r\n}\r\n<\/code><\/pre>\n<p>You can now show that and where the implicit conversion kicks in. The great benefit of C++ Insights as an online tool is that you can change the signature of <code>UnsignedIntFunction<\/code> to <code>int<\/code> and see the implicit conversion disappear. This is powerful as your students do not just have to believe you, they can see it and experiment with it themselves. I frequently tell my students not to trust me and challenge what I\u2019m telling them. With C++ Insights they easily can. Sadly for me, they sometimes find my mistakes, but that is a different story.<\/p>\n<\/p>\n<h3>Classes<\/h3>\n<p>Let\u2019s move on to something more complex like classes with conversion operators things get more tricky to spot. At this point, we added operator overloading to the picture. The question is, which overload gets selected when? There was a recent tweet by <a href=\"https:\/\/twitter.com\/walletfox\/status\/1082224984670507008\">@walletfox<\/a> illustrating how C++ Insights can help to show which overload&nbsp;&nbsp;<code>std::cout<\/code> gets selected. Consider this, <code>cout<\/code>-free <a href=\"https:\/\/cppinsights.io\/lnk?code=Y2xhc3MgRm9vCnsKcHVibGljOgogICAgRm9vKGludCB2KQogICAgOiBtVnt2fQogICAgewogICAgfQoKICAgIEZvbyYgb3BlcmF0b3IrPShjb25zdCBGb28mIHJocykKICAgIHsKICAgICAgICBtViArPSByaHMubVY7CiAgICAgICAgcmV0dXJuICp0aGlzOwogICAgfQoKICAgIG9wZXJhdG9yIGludCgpIHsgcmV0dXJuIG1WOyB9Cgpwcml2YXRlOgogICAgaW50IG1WOwp9OwoKaW50IG1haW4oKQp7CiAgICBGb28gdCgyKTsKICAgIHQgPSAzICogMjsKCiAgICBGb28gdHQoNCk7CiAgICB0ICs9IHR0ICogMjsKfQ==&amp;rev=1.0\">example<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">class<\/span> Foo\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n    Foo(<span class=\"hljs-keyword\">int<\/span> v)\r\n    : mV{v}\r\n    {\r\n    }\r\n\r\n    Foo&amp; <span class=\"hljs-keyword\">operator<\/span>+=(<span class=\"hljs-keyword\">const<\/span> Foo&amp; rhs)\r\n    {\r\n        mV += rhs.mV;\r\n        <span class=\"hljs-keyword\">return<\/span> *<span class=\"hljs-keyword\">this<\/span>;\r\n    }\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">operator<\/span> <span class=\"hljs-title\">int<\/span><span class=\"hljs-params\">()<\/span> <\/span>{ <span class=\"hljs-keyword\">return<\/span> mV; }\r\n\r\n<span class=\"hljs-keyword\">private<\/span>:\r\n    <span class=\"hljs-keyword\">int<\/span> mV;\r\n};\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n    <span class=\"hljs-function\">Foo <span class=\"hljs-title\">t<\/span><span class=\"hljs-params\">(<span class=\"hljs-number\">2<\/span>)<\/span><\/span>;\r\n    t = <span class=\"hljs-number\">3<\/span> * <span class=\"hljs-number\">2<\/span>;\r\n\r\n    <span class=\"hljs-function\">Foo <span class=\"hljs-title\">tt<\/span><span class=\"hljs-params\">(<span class=\"hljs-number\">4<\/span>)<\/span><\/span>;\r\n    t += tt * <span class=\"hljs-number\">2<\/span>;\r\n}\r\n<\/code><\/pre>\n<p>The question is, do you directly spot what happens for <code>t = 3 * 2<\/code> and <code>t += tt * 2<\/code>? Running C++ Insights on it gives the following output:<\/p>\n<pre><code class=\"language-C++\">class Foo\r\n{\r\npublic:\r\n    inline Foo(int v)\r\n    : mV{v}\r\n    {\r\n    }\r\n    \r\n    \r\n\r\n    inline Foo &amp; operator+=(const Foo &amp; rhs)\r\n    {\r\n      this-&gt;mV += rhs.mV;\r\n      return *this;\r\n    }\r\n    \r\n\r\n    using retType = int;\r\n    inline operator retType ()\r\n    {\r\n      return this-&gt;mV;\r\n    }\r\n    \r\n\r\nprivate:\r\n    int mV;\r\n\/* public: inline constexpr Foo(const Foo &amp;); *\/\r\n\/* public: inline constexpr Foo(Foo &amp;&amp;); *\/\r\n\/* public: inline Foo &amp; operator=(const Foo &amp;); *\/\r\n\/* public: inline Foo &amp; operator=(Foo &amp;&amp;) noexcept; *\/\r\n\/* public: inline ~Foo() noexcept; *\/\r\n};\r\n\r\nint main()\r\n{\r\n  Foo t = Foo(2);\r\n  t.operator=(Foo(3 * 2));\r\n  Foo tt = Foo(4);\r\n  t.operator+=(Foo(static_cast&lt;int&gt;(tt.operator int()) * 2));\r\n}\r\n<\/code><\/pre>\n<p>Aside from the question, you can see implicit member functions the compiler adds like copy and move operations as well as the destructor. You also see the answer to the original question; there are implicit conversions. Both times a temporary object of <code>Foo<\/code> is created which then gets passed to <code>operator=(const Foo&amp;)<\/code> and <code>operator+=(const Foo)<\/code>. We did not implement the first one. In addition to all this, the conversion operator <code>operator int()<\/code> is also used to first convert a <code>Foo<\/code> object to an <code>int<\/code> just multiply it by 2 and then pass the result in a temporary <code>Foo<\/code> object.<\/p>\n<h4>Special Member Functions<\/h4>\n<p>Another thing C++ Insights shows us, you have already seen it, are the special member functions the compiler generates for us. In the example above, we can see the copy and move constructor as well as the copy and move assignment operators. Here is an example demonstrating it even <a href=\"https:\/\/cppinsights.io\/lnk?code=Y2xhc3MgQQp7CnB1YmxpYzoKICBBKCkgPSBkZWZhdWx0OwogIEEoY29uc3QgQSYpIHt9Cn07CgpjbGFzcyBCCnsKcHVibGljOgp9OwoKaW50IG1haW4oKQp7CiAgQSBhOwogIEEgYTI7CiAgLy9hID0gYTI7CiAgCiAgQiBiOwp9&amp;std=cpp17&amp;rev=1.0\">better<\/a>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">class<\/span> A\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n  A() = <span class=\"hljs-keyword\">default<\/span>;\r\n  A(<span class=\"hljs-keyword\">const<\/span> A&amp;) {}\r\n};\r\n\r\n<span class=\"hljs-keyword\">class<\/span> B\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n};\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  A a;\r\n  A a2;\r\n  <span class=\"hljs-comment\">\/\/a = a2;<\/span>\r\n  \r\n  B b;\r\n}\r\n<\/code><\/pre>\n<p>In class <code>A<\/code> we do provide a copy constructor. With that, the compiler does no longer generate the move operations for this class as it does for <code>B<\/code>:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">class<\/span> A\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n  A() = <span class=\"hljs-keyword\">default<\/span>;\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-title\">A<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">const<\/span> A &amp;)<\/span>\r\n  <\/span>{\r\n  }\r\n  \r\n  \r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr A() noexcept;<\/span>\r\n};\r\n\r\n<span class=\"hljs-keyword\">class<\/span> B\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr B() noexcept;<\/span>\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr B(const B &amp;);<\/span>\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr B(B &amp;&amp;);<\/span>\r\n};\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  A a = A();\r\n  A a2 = A();\r\n  B b = B();\r\n}\r\n<\/code><\/pre>\n<p>What you can see in addition is, that the special members are only generated if needed. In the code as it is, there is no assignment operator. However, if we enable the line <code>a = a2<\/code> we get one:<\/p>\n<pre><code class=\"language-C++\"><span class=\"hljs-keyword\">class<\/span> A\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n  A() = <span class=\"hljs-keyword\">default<\/span>;\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">inline<\/span> <span class=\"hljs-title\">A<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">const<\/span> A &amp;)<\/span>\r\n  <\/span>{\r\n  }\r\n  \r\n  \r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr A() noexcept;<\/span>\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr A &amp; operator=(const A &amp;) noexcept;<\/span>\r\n};\r\n\r\n<span class=\"hljs-keyword\">class<\/span> B\r\n{\r\n<span class=\"hljs-keyword\">public<\/span>:\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr B() noexcept;<\/span>\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr B(const B &amp;);<\/span>\r\n<span class=\"hljs-comment\">\/\/ public: inline constexpr B(B &amp;&amp;);<\/span>\r\n};\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>\r\n<\/span>{\r\n  A a = A();\r\n  A a2 = A();\r\n  a.<span class=\"hljs-keyword\">operator<\/span>=(a2);\r\n  B b = B();\r\n}\r\n<\/code><\/pre>\n<p>I think that the power of C++ Insights is that you can see how a code change on your side affects what the compiler adds or selects. It\u2019s more or less like the brilliant <a href=\"https:\/\/godbolt.org\/\">compiler explorer <\/a>except for it spits the result out in a language we all understand well.<\/p>\n<p>I\u2019d like to thank Rainer for the opportunity to share information about C++ Insights on his popular blog!<\/p>\n<p>Have fun with C++ Insights. You can support the project by becoming a <a href=\"https:\/\/www.patreon.com\/cppinsights\">Patreon<\/a> or of course with code <a href=\"https:\/\/github.com\/andreasfertig\/cppinsights\">contributions<\/a>.<\/p>\n<p>Stay tuned for more insights about C++ Insights to type deduction \u2026<\/p>\n<p><strong>Andreas<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m totally happy to announce that this post starts a series of posts to C++ Insights. C++ Insights is an awesome tool that I use heavily in my posts and in my classes to show the magic of the C++ compiler.<\/p>\n","protected":false},"author":21,"featured_media":5651,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[374],"tags":[474],"class_list":["post-5652","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cppinsight","tag-conversions"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5652","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=5652"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5652\/revisions"}],"predecessor-version":[{"id":6794,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5652\/revisions\/6794"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5651"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}