{"id":5344,"date":"2017-11-10T12:50:14","date_gmt":"2017-11-10T12:50:14","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-more-rules-to-overloading\/"},"modified":"2023-06-26T12:02:13","modified_gmt":"2023-06-26T12:02:13","slug":"c-core-guidelines-more-rules-to-overloading","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-more-rules-to-overloading\/","title":{"rendered":"C++ Core Guidelines: More Rules for Overloading"},"content":{"rendered":"<p>I started the last post on my journey through the rules for overloading functions and operators. Let me continue and finish my journey with this post.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5341\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/genetic.png\" alt=\"genetic\" width=\"500\" height=\"420\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/genetic.png 783w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/genetic-300x252.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/genetic-768x645.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>First, here are all ten rules for functions and operators.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conventional\">C.160: Define operators primarily to mimic conventional usage<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-symmetric\">C.161: Use nonmember functions for symmetric operators<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-equivalent\">C.162: Overload operations that are roughly equivalent<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-equivalent-2\">C.163: Overload only for operations that are roughly equivalent<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conversion\">C.164: Avoid conversion operators<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-custom\">C.165: Use <code class=\"highlighter-rouge no-highlight\">using<\/code> for customization points<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-address-of\">C.166: Overload unary <code class=\"highlighter-rouge no-highlight\">&amp;<\/code> only as part of a system of smart pointers and references<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-overload\">C.167: Use an operator for an operation with its conventional meaning<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-namespace\">C.168: Define overloaded operators in the namespace of their operands<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-lambda\">C.170: If you feel like overloading a lambda, use a generic lambda<\/a><\/li>\n<\/ul>\n<p>Our journey continues with rule C.164. That is quite an important rule.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-conversion\">C.164: Avoid conversion operators<\/a><\/h3>\n<p>If you want fun, overload the operator bool and make it not explicit. This means that type conversion from <span style=\"font-family: courier new,courier;\">bool<\/span> to <span style=\"font-family: courier new,courier;\">int&nbsp;<\/span>can happen.<\/p>\n<p>But I should be serious. Let me design a class <span style=\"font-family: courier new,courier;\">MyHouse<\/span>, which can be bought by a family; therefore, I decided to implement the operator bool to check if a family has bought the house efficiently.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/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: #0099ff; font-style: italic;\">\/\/ implicitConversion.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyHouse{\r\n  MyHouse() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n  MyHouse(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> fam)<span style=\"color: #555555;\">:<\/span> family(fam){}\r\n\t\r\n  <span style=\"color: #006699; font-weight: bold;\">operator<\/span> <span style=\"color: #007788; font-weight: bold;\">bool<\/span>(){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> not family.empty(); }               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ explicit operator bool(){ return not family.empty(); }   \/\/ (2)<\/span>\r\n\t\r\n  std<span style=\"color: #555555;\">::<\/span>string family <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"\"<\/span>;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\t\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\t\r\n  MyHouse firstHouse;\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (not firstHouse){                                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"firstHouse is already sold.\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  };\r\n\t\r\n  MyHouse secondHouse(<span style=\"color: #cc3300;\">\"grimm\"<\/span>);                               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> (secondHouse){\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Grimm bought secondHouse.\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  }\r\n\t\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\t\r\n  <span style=\"color: #007788; font-weight: bold;\">int<\/span> myNewHouse <span style=\"color: #555555;\">=<\/span> firstHouse <span style=\"color: #555555;\">+<\/span> secondHouse;                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> myNewHouse2 <span style=\"color: #555555;\">=<\/span> (<span style=\"color: #ff6600;\">20<\/span> <span style=\"color: #555555;\">*<\/span> firstHouse <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">10<\/span> <span style=\"color: #555555;\">*<\/span> secondHouse) <span style=\"color: #555555;\">\/<\/span> secondHouse;\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"myNewHouse: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> myNewHouse <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"myNewHouse2: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> myNewHouse2 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\t\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, I can quickly check with the operator bool (1) if a family (4) or no family (3) lives in the house. Fine. But due to the implicit operator bool, I can use my house in arithmetic expressions (5). That was not my intention.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5342\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversion.png\" alt=\"implicitConversion\" width=\"400\" height=\"226\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversion.png 689w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversion-300x170.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>This is weird. Since C++11, you can make conversion operators explicit; therefore, no implicit conversion to <span style=\"font-family: courier new,courier;\">int<\/span> will kick in. I have to make the operator bool explicit (2), and adding houses is not possible anymore, but I can use a house in logical expressions.&nbsp;<\/p>\n<p>Now, the compilation of the program fails.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5343\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversionError.png\" alt=\"implicitConversionError\" width=\"600\" height=\"243\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversionError.png 1535w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversionError-300x121.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversionError-1024x414.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/11\/implicitConversionError-768x311.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-custom\">C.165: Use <code class=\"highlighter-rouge no-highlight\">using<\/code> for customization points<\/a><\/h3>\n<p>This rule is quite unique; therefore, I will make it short. There are about 50 overloads for <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/algorithm\/swap\">std::swap<\/a> available in the C++ standard. It&#8217;s pretty probable that you already implemented swap for your own type: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-comparison-swap-and-hash\">C++ Core Guidelines: Comparison, Swap, and Hash<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">namespace<\/span> N {\r\n    My_type X { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">swap<\/span>(X<span style=\"color: #555555;\">&amp;<\/span>, X<span style=\"color: #555555;\">&amp;<\/span>);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ optimized swap for N::X<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ ...<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Because of argument-dependent lookup (see C.168), the compiler will find your swap implementation. Using the generic std::swap as a kind of fallback is a good idea.<span style=\"font-family: courier new,courier;\"> std::swap<\/span> maybe not be optimized for your data type, but at least it works. You can achieve that by introducing the function <span style=\"font-family: courier new,courier;\">std::swap<\/span>.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">void<\/span> <span style=\"color: #cc00ff;\">f3<\/span>(N<span style=\"color: #555555;\">::<\/span>X<span style=\"color: #555555;\">&amp;<\/span> a, N<span style=\"color: #555555;\">::<\/span>X<span style=\"color: #555555;\">&amp;<\/span> b)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> std<span style=\"color: #555555;\">::<\/span>swap;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ make std::swap available<\/span>\r\n    swap(a, b);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ calls N::swap if it exists, otherwise std::swap<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-address-of\">C.166: Overload unary <code class=\"highlighter-rouge no-highlight\">&amp;<\/code> only as part of a system of smart pointers and references<\/a><\/h3>\n<p>Honestly, this rule is way too special to write about in this post. If you want to create a proxy by overloading the unary operator &amp;, you should know the consequences.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-overload\">C.167: Use an operator for an operation with its conventional meaning<\/a><\/h3>\n<p id=\"h1-1-c-160-define-operators-primarily-to-mimic-conventional-usage\">This rule is similar to rule C.160: Define operators primarily to mimic conventional usage. I referred to it in my last post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-for-overloading-and-overload-operators\">C++ Core Guidelines: Rules for Overloading and Overload Operators<\/a>.<\/p>\n<p>This rule applies to a lot of operators.<\/p>\n<ul>\n<li><span style=\"font-family: courier new,courier;\">&lt;&lt;, &gt;&gt;<\/span>: input and output<\/li>\n<li><span style=\"font-family: courier new,courier;\"><code class=\"highlighter-rouge no-highlight\">==<\/code>, <code class=\"highlighter-rouge no-highlight\">!=<\/code>, <code class=\"highlighter-rouge no-highlight\">&lt;<\/code>, <code class=\"highlighter-rouge no-highlight\">&lt;=<\/code>, <code class=\"highlighter-rouge no-highlight\">&gt;<\/code>, <\/span><span style=\"font-family: courier new,courier;\">and <\/span><span style=\"font-family: courier new,courier;\"><code class=\"highlighter-rouge no-highlight\">&gt;=<\/code><\/span>: comparison<\/li>\n<li><span style=\"font-family: courier new,courier;\"><code class=\"highlighter-rouge no-highlight\">+<\/code>, <code class=\"highlighter-rouge no-highlight\">-<\/code>, <code class=\"highlighter-rouge no-highlight\">*<\/code>, <code class=\"highlighter-rouge no-highlight\">\/<\/code>, <\/span><span style=\"font-family: courier new,courier;\">and<\/span><span style=\"font-family: courier new,courier;\"> <code class=\"highlighter-rouge no-highlight\">%<\/code><\/span>: arithmetic<\/li>\n<li><span style=\"font-family: courier new,courier;\"><code class=\"highlighter-rouge no-highlight\">.<\/code>, <code class=\"highlighter-rouge no-highlight\">-&gt;<\/code>, <\/span><span style=\"font-family: courier new,courier;\">unary <\/span><span style=\"font-family: courier new,courier;\"><code class=\"highlighter-rouge no-highlight\">*<\/code>, <\/span><span style=\"font-family: courier new,courier;\">and <\/span><span style=\"font-family: courier new,courier;\"><code class=\"highlighter-rouge no-highlight\">[]<\/code><\/span>: access<\/li>\n<li><code class=\"highlighter-rouge no-highlight\">=<\/code>: assignment<\/li>\n<\/ul>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-namespace\">C.168: Define overloaded operators in the namespace of their operands<\/a><\/h3>\n<p>ADL is a special property in C++, making our life as a programmer easier. ADL stands for argument-dependent lookup. Sometimes it is called Koenig lookup. It means that for <strong>unqualified<\/strong> function calls, the functions in the namespace of the function arguments are considered by the C++ runtime. For more details about ADL, read here: <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/adl\">argument-dependent lookup.<\/a><\/p>\n<p>Only to remind you and give you a short example: because of ADL, the C++ runtime will find the right operator == in the namespace of the operands.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">namespace<\/span> N {\r\n    <span style=\"color: #006699; font-weight: bold;\">struct<\/span> S { };\r\n    <span style=\"color: #007788; font-weight: bold;\">bool<\/span> <span style=\"color: #006699; font-weight: bold;\">operator<\/span><span style=\"color: #555555;\">==<\/span>(S, S);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK: in the same namespace as S, and even next to S<\/span>\r\n}\r\n\r\nN<span style=\"color: #555555;\">::<\/span>S s;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">bool<\/span> x <span style=\"color: #555555;\">=<\/span> (s <span style=\"color: #555555;\">==<\/span> s);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ finds N::operator==() by ADL<\/span>\r\n<\/pre>\n<\/div>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Ro-lambda\">C.170: If you feel like overloading a lambda, use a generic lambda<\/a><\/h3>\n<p>This rule is relatively easy to get. You can not overload a lambda. With C++14, you can overcome this restriction by implementing a generic lambda.<\/p>\n<p><!-- HTML generated using hilite.me --><\/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;\">auto<\/span> g <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #007788; font-weight: bold;\">int<\/span>) { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> g <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #007788; font-weight: bold;\">double<\/span>) { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };   <span style=\"color: #0099ff; font-style: italic;\">\/\/ error: cannot overload lambdas<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> h <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span>) { <span style=\"color: #0099ff; font-style: italic;\">\/* ... *\/<\/span> };   <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Maybe you know it. A lambda is just an instance of a class for which the call operator is overloaded, or to say in other words, a <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/utility\/functional\">function object<\/a>. In addition, a generic lambda is a function object with a templatized call operator. That&#8217;s all.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>There are four rules for the particular class type union. I&#8217;m unsure if I will dedicate the <a href=\"https:\/\/goo.gl\/WaohAC\">next post<\/a> to unions. Afterward, I&#8217;m done with classes and class hierarchies and will write about enumerations.<\/p>\n<p>I&#8217;m pretty happy that I made this post just in time because I had a lot of fascinating discussions about the future of C++ at the <a href=\"http:\/\/meetingcpp.com\/\">Meeting C++ in Berlin<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I started the last post on my journey through the rules for overloading functions and operators. Let me continue and finish my journey with this post.<\/p>\n","protected":false},"author":21,"featured_media":5341,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[499,501],"class_list":["post-5344","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-classes","tag-overloading"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5344","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=5344"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5344\/revisions"}],"predecessor-version":[{"id":6852,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5344\/revisions\/6852"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5341"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}