{"id":5655,"date":"2019-03-20T06:35:03","date_gmt":"2019-03-20T06:35:03","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-insights-type-deduction\/"},"modified":"2023-06-26T10:13:04","modified_gmt":"2023-06-26T10:13:04","slug":"c-insights-type-deduction","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-insights-type-deduction\/","title":{"rendered":"C++ Insights &#8211; Type Deduction"},"content":{"rendered":"<p>Andreas Fertigs story with C++ Insights goes on. This weeks post is about type deduction with <code>auto<\/code> and <code>decltype <\/code>or as I often phrase it: &#8220;Use the smartness of the compiler.&#8221;<\/p>\n<p><!--more--><\/p>\n<h2><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5654\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/02-type-deduction.png\" alt=\"02 type deduction\" width=\"600\" height=\"338\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/02-type-deduction.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/02-type-deduction-300x169.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/02-type-deduction-1024x576.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/03\/02-type-deduction-768x432.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/h2>\n<h2>Type Deduction<\/h2>\n<p>&nbsp;<\/p>\n<p>With C++11 we got <code>auto<\/code> and <code>decltype<\/code> and, therefore, two new forms of type deduction. We are used to type deduction from templates, however, these two new variants can be tricky sometimes.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">auto<\/span><\/h3>\n<p>&nbsp;<\/p>\n<p>Consider this example:<\/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: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>()\r\n{\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> ip;\r\n  <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> cip;\r\n  <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> cicp <span style=\"color: #555555;\">=<\/span> ip;\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> aip <span style=\"color: #555555;\">=<\/span> ip;\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> acip <span style=\"color: #555555;\">=<\/span> cip;\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> acicp <span style=\"color: #555555;\">=<\/span> cicp;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>We have three different pointers, all of type <code>int<\/code>. They are getting more and more constified. The question is what\u2019s the type that is deduced by <code>auto<\/code>? All are pointers, that\u2019s for sure. But what happens with the <code>const<\/code>? <code>auto<\/code> removes all top-level qualifier. Hence, even the <code>const<\/code> disappears. Does it? Here is the output C++ Insights gives:<\/p>\n<p>&nbsp;<\/p>\n<pre><code class=\"language-C++\"><span style=\"font-family: courier new, courier;\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span><br \/><\/span>{<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">int<\/span> * ip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> * cip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> *<span class=\"hljs-keyword\">const<\/span> cicp = ip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">int<\/span> * aip = ip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> * acip = cip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> * acicp = cicp;<\/span><br \/><span style=\"font-family: courier new, courier;\">}<\/span><br \/><\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>Yes, the top-level <code>const<\/code> is removed. A constant pointer does not matter, so this <code>const<\/code> is discarded, but the constness of the memory behind it sticks. Hence, this <code>const<\/code> is preserved. Which is why <code>acip<\/code> looks exactly like <code>acicp<\/code>. This makes sense right.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">decltype(auto)<\/span><\/h3>\n<p>Now, from time to time we like to preserve all qualifiers. This is when <code>decltype<\/code> appears. In contrast to <code>auto<\/code>, <code>decltype<\/code> does preserve all top-level qualifiers. With&nbsp; <ins>C++14 the combination of <code>decltype<\/code> and <code>auto<\/code> is possible and we can write <code>decltype(auto)<\/code> which makes things easier. Here is another example from C++<\/ins> Insights which uses C++14:<\/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: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>()\r\n{\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> ip;\r\n  <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> cip;\r\n  <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> cicp <span style=\"color: #555555;\">=<\/span> ip;\r\n\r\n \r\n\r\n  decltype(<span style=\"color: #006699; font-weight: bold;\">auto<\/span>) aip <span style=\"color: #555555;\">=<\/span> ip;\r\n  decltype(<span style=\"color: #006699; font-weight: bold;\">auto<\/span>) acip <span style=\"color: #555555;\">=<\/span> cip;\r\n  decltype(<span style=\"color: #006699; font-weight: bold;\">auto<\/span>) acicp <span style=\"color: #555555;\">=<\/span> cicp;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>From this we get the following output:<\/p>\n<p>&nbsp;<\/p>\n<pre><code class=\"language-C++\"><span style=\"font-family: courier new, courier;\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span><br \/><\/span>{<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">int<\/span> * ip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> * cip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> *<span class=\"hljs-keyword\">const<\/span> cicp = ip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">int<\/span> * aip = ip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> * acip = cip;<\/span><br \/><span style=\"font-family: courier new, courier;\">  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">int<\/span> *<span class=\"hljs-keyword\">const<\/span> acicp = cicp;<\/span><br \/><span style=\"font-family: courier new, courier;\">}<\/span><br \/><\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>We can see, that <code>acicp<\/code> does carry the second <code>const<\/code> which is lost when we just use <span style=\"font-family: courier new, courier;\"><code>auto<\/code><\/span>.<\/p>\n<\/p>\n<h3><span style=\"font-family: courier new, courier;\">decltype<\/span><\/h3>\n<p>When do we need <code>decltype<\/code>, or more precisely when do we like to keep all qualifiers? One popular reason is templates. Imagine a class template with some function Get. With just using <code>auto<\/code>&nbsp;it as a return type we can never return a reference to something. In template code, we often don\u2019t know the exact types, which makes it desirable to provide code that just works. <code>decltype<\/code> can help here. However, consider <code>decltype<\/code>&nbsp;a library writer feature. In most cases, we are fine with <code>auto<\/code>. It is just good to know the entire toolbox.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">auto&amp; and auto* versus auto<\/span><\/h3>\n<p>What we\u2018ve seen so far is, that we need to be explicit, if it comes to <code>auto<\/code> and references. We must always write <code>auto&amp;<\/code> to get a reference. How is it with pointers? There <code>auto<\/code> gives us the correct type, so we can spare the star? This is in fact a question I frequently get from my students. The answer is: it depends. I recommend writing it just for consistency. However, there are scenarios where we indeed need auto* even that <code>auto<\/code> did deduce the correct type. Consider this <a href=\"https:\/\/cppinsights.io\/lnk?code=c3RydWN0IEZvb3t9OwoKRm9vKiBHZXRGb28oKQp7CiAgc3RhdGljIEZvbyBmb287CiAgCiAgcmV0dXJuICZmb287Cn0KCmludCBtYWluKCkKewogIGF1dG8gZnAgPSBHZXRGb28oKTsKfQ==&amp;rev=1.0\">example<\/a>:<\/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: #006699; font-weight: bold;\">struct<\/span> Foo{};\r\n\r\nFoo<span style=\"color: #555555;\">*<\/span> <span style=\"color: #cc00ff;\">GetFoo<\/span>()\r\n{\r\n   <span style=\"color: #006699; font-weight: bold;\">static<\/span> Foo foo;\r\n\r\n   <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">&amp;<\/span>foo;\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  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fp <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>We have a function returning a <code>Foo*<\/code> and an <code>auto<\/code> variable <code>auto f = GetFoo()<\/code> which deduces the type. Of course, the correct type. What if we\u2019d like to make <code>f<\/code> const? That we cannot alter the data of <code>f<\/code>? Sure, we write it like this <code>const auto f = ...<\/code>. At least that\u2019s what we would do if we write it without <code>auto<\/code>. Here are some possibilities we can try:<\/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: #006699; font-weight: bold;\">struct<\/span> Foo{};\r\n\r\nFoo<span style=\"color: #555555;\">*<\/span> <span style=\"color: #cc00ff;\">GetFoo<\/span>()\r\n{\r\n   <span style=\"color: #006699; font-weight: bold;\">static<\/span> Foo foo;\r\n\r\n   <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">&amp;<\/span>foo;\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   <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fp0 <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n   <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span> fp1 <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> fp2 <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n   <span style=\"color: #0099ff; font-style: italic;\">\/\/const auto const fp3 = GetFoo(); does not compile<\/span>\r\n   <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> fp4 <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> fp5 <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n   <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">*<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> fp6 <span style=\"color: #555555;\">=<\/span> GetFoo();\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>First, <code>fp1<\/code> produces a const pointer to mutable data. Not exactly what we intended. <code>fp2<\/code> probably seems pointless. <code>fp3<\/code> makes more sense, but this doesn\u2019t compile. The control changes, if we start using the form <code>auto*<\/code>. Now, we can add the qualifiers like we can do it with a regular type. But <a href=\"https:\/\/cppinsights.io\/lnk?code=c3RydWN0IEZvb3t9OwoKRm9vKiBHZXRGb28oKQp7CiAgc3RhdGljIEZvbyBmb287CiAgCiAgcmV0dXJuICZmb287Cn0KCmludCBtYWluKCkKewogICAgICAgIGF1dG8gICAgICAgIGZwMCA9IEdldEZvbygpOwogIGNvbnN0IGF1dG8gICAgICAgIGZwMSA9IEdldEZvbygpOwogICAgICAgIGF1dG8gIGNvbnN0IGZwMiA9IEdldEZvbygpOwogIGNvbnN0IGF1dG8qICAgICAgIGZwMyA9IEdldEZvbygpOwogICAgICAgYXV0byogIGNvbnN0IGZwNCA9IEdldEZvbygpOwp9&amp;rev=1.0\">see<\/a> for yourself in C++ Insights what the result is:<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"font-family: courier new, courier;\">struct Foo{\/* public: inline constexpr Foo() noexcept; *\/<\/span><br \/><span style=\"font-family: courier new, courier;\">\/* public: inline constexpr Foo(const Foo &amp;); *\/<\/span><br \/><span style=\"font-family: courier new, courier;\">\/* public: inline constexpr Foo(Foo &amp;&amp;); *\/<\/span><br \/><span style=\"font-family: courier new, courier;\">};<\/span><\/pre>\n<p><span style=\"font-family: courier new, courier;\">Foo * GetFoo()<\/span><br \/><span style=\"font-family: courier new, courier;\">{<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; static Foo foo = Foo();<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; return &amp;foo;<\/span><br \/><span style=\"font-family: courier new, courier;\">}<\/span><\/p>\n<p><span style=\"font-family: courier new, courier;\">int main()<\/span><br \/><span style=\"font-family: courier new, courier;\">{<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; Foo * fp0 = GetFoo();<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; Foo *const fp1 = GetFoo();<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; Foo *const fp2 = GetFoo();<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; const Foo * fp4 = GetFoo();<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; Foo *const fp5 = GetFoo();<\/span><br \/><span style=\"font-family: courier new, courier;\">&nbsp;&nbsp; const Foo *const fp6 = GetFoo();<\/span><br \/><span style=\"font-family: courier new, courier;\">}<\/span><code class=\"language-C++\"><br \/><\/code><\/p>\n<p>&nbsp;<\/p>\n<p>The simple advice is: always be explicit and use the form <code>auto&amp;<\/code> as well as <code>auto*<\/code> even if auto is able to deduce a pointer type.<\/p>\n<p>&nbsp;<\/p>\n<p>Let\u2019s say we are explicit and use <code>auto&amp;<\/code>. Look at this <a href=\"https:\/\/cppinsights.io\/lnk?code=c3RydWN0IFNpbmdsZXRvbnt9OwoKYXV0byBHZXQoKQp7CiAgc3RhdGljIFNpbmdsZXRvbiBze307CiAgCiAgcmV0dXJuIHM7Cn0KCmludCBtYWluKCkKewogIGF1dG8mIHggPSBHZXQoKTsKfQ==&amp;std=cpp17&amp;rev=1.0\">example<\/a>:<\/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: #006699; font-weight: bold;\">struct<\/span> Singleton{};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">Get<\/span>()\r\n{\r\n   <span style=\"color: #006699; font-weight: bold;\">static<\/span> Singleton s{};\r\n\r\n   <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\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   <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> x <span style=\"color: #555555;\">=<\/span> Get();\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>We have a classical singleton which the function <code>Get<\/code> should return. Of course, we like a reference to it otherwise we have multiple tons. Despite <code>auto<\/code> and <code>&amp;<\/code> this code does not compile:<\/p>\n<pre><code>error: non-const lvalue reference to type 'Singleton' cannot bind to a temporary of type 'Singleton'<br \/><\/code><\/pre>\n<p>The reason is, the <code>Get<\/code> in fact return <code>Singleton<\/code> and not <code>Singleton&amp;<\/code>. Why? Because we did not apply the <code>&amp;<\/code> to the auto-return type of <code>Get<\/code>. A small change and the code compiles:<\/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: #006699; font-weight: bold;\">struct<\/span> Singleton{};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> Get()\r\n{\r\n   <span style=\"color: #006699; font-weight: bold;\">static<\/span> Singleton s{};\r\n\r\n   <span style=\"color: #006699; font-weight: bold;\">return<\/span> s;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main()\r\n{\r\n   <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> x <span style=\"color: #555555;\">=<\/span> Get();\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/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 template instantiation \u2026<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Andreas<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Andreas Fertigs story with C++ Insights goes on. This weeks post is about type deduction with auto and decltype or as I often phrase it: &#8220;Use the smartness of the compiler.&#8221;<\/p>\n","protected":false},"author":21,"featured_media":5654,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[374],"tags":[436,437],"class_list":["post-5655","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cppinsight","tag-auto","tag-decltype"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5655","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=5655"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5655\/revisions"}],"predecessor-version":[{"id":6793,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5655\/revisions\/6793"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5654"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5655"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}