{"id":5024,"date":"2016-11-11T06:51:27","date_gmt":"2016-11-11T06:51:27","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/constant-expressions-with-constexpr\/"},"modified":"2023-06-26T12:36:33","modified_gmt":"2023-06-26T12:36:33","slug":"constant-expressions-with-constexpr","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/constant-expressions-with-constexpr\/","title":{"rendered":"Constant Expressions with constexpr"},"content":{"rendered":"<p>You can define with the keyword <span style=\"font-family: courier new,courier;\">constexpr<\/span> an expression that can be evaluated at compile time. <span style=\"font-family: courier new,courier;\">constexpr<\/span> can be used for variables, functions, and user-defined types. An expression that is evaluated at compile time has a lot of advantages. For example, <span style=\"font-family: courier new,courier;\">constexpr<\/span> variables and instances of user-defined types are automatically thread-safe and can be stored in ROM; <span style=\"font-family: courier new,courier;\">constexpr<\/span> functions evaluated at compile-time are done with their work at run time.<\/p>\n<p><!--more--><\/p>\n<h2>All done at compile time<\/h2>\n<p>I already have indicated it in my post on <a href=\"https:\/\/www.modernescpp.com\/index.php\/user-defined-literals\">User-defined literals.&nbsp; <\/a>The calculation of how many kilometers per week I drive on average has a massive optimization potential. In this post, I will solve my promise. To make it easy for you. Here is the program from the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/user-defined-literals\">User-defined literals<\/a> once more.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n61\r\n62\r\n63\r\n64\r\n65\r\n66\r\n67\r\n68\r\n69\r\n70\r\n71\r\n72\r\n73\r\n74\r\n75\r\n76\r\n77\r\n78\r\n79\r\n80<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ userdefinedLiterals.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">namespace<\/span> Distance{\r\n\r\n  <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyDistance<\/span>{\r\n    public:\r\n      MyDistance(<span style=\"color: #2b91af;\">double<\/span> i):m(i){}\r\n\r\n      <span style=\"color: #0000ff;\">friend<\/span> MyDistance <span style=\"color: #0000ff;\">operator<\/span>+(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; b){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m + b.m);\r\n      }\r\n      <span style=\"color: #0000ff;\">friend<\/span> MyDistance <span style=\"color: #0000ff;\">operator<\/span>-(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a,<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; b){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m - b.m);\r\n      }\r\n\t  \r\n      <span style=\"color: #0000ff;\">friend<\/span> MyDistance <span style=\"color: #0000ff;\">operator<\/span>*(<span style=\"color: #2b91af;\">double<\/span> m, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(m*a.m);<br \/>      }\r\n\t   <br \/>     <span style=\"color: #0000ff;\">friend<\/span> MyDistance <span style=\"color: #0000ff;\">operator<\/span>\/(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a, <span style=\"color: #2b91af;\">int<\/span> n){\r\n       <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m\/n);\r\n     }\r\n\t  \r\n     <span style=\"color: #0000ff;\">friend<\/span> std::ostream&amp; <span style=\"color: #0000ff;\">operator<\/span>&lt;&lt; (std::ostream &amp;out, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; myDist){\r\n       out &lt;&lt; myDist.m &lt;&lt; <span style=\"color: #a31515;\">\" m\"<\/span>;\r\n       <span style=\"color: #0000ff;\">return<\/span> out;\r\n      }\r\n    private:\r\n      <span style=\"color: #2b91af;\">double<\/span> m;\t  \r\n  };\r\n\r\n  <span style=\"color: #0000ff;\">namespace<\/span> Unit{\r\n    MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _km(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> d){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(1000*d);\r\n    }\r\n    MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _m(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> m){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(m);\r\n    }\r\n    MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _dm(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> d){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(d\/10);\r\n    }\r\n    MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _cm(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> c){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(c\/100);\r\n    }\r\n  }\r\n  \r\n}\r\n  \r\nDistance::MyDistance getAverageDistance(std::initializer_list&lt;Distance::MyDistance&gt; inList){\r\n  <span style=\"color: #0000ff;\">auto<\/span> sum= Distance::MyDistance{0.0};\r\n  <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #0000ff;\">auto<\/span> i: inList) sum = sum + i ;\r\n  <span style=\"color: #0000ff;\">return<\/span> sum\/inList.size(); \r\n}\r\n\r\n\r\n<span style=\"color: #0000ff;\">using<\/span> <span style=\"color: #0000ff;\">namespace<\/span> Distance::Unit;\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std:: cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #0000ff;\">auto<\/span> work= 63.0_km;\r\n  <span style=\"color: #0000ff;\">auto<\/span> workPerDay= 2 * work;\r\n  <span style=\"color: #0000ff;\">auto<\/span> abbrevationToWork= 5400.0_m;\r\n  <span style=\"color: #0000ff;\">auto<\/span> workout= 2 * 1600.0_m;\r\n  <span style=\"color: #0000ff;\">auto<\/span> shopping= 2 * 1200.0_m;\r\n  \r\n  <span style=\"color: #0000ff;\">auto<\/span> distPerWeek1= 4*workPerDay-3*abbrevationToWork+ workout+ shopping;\r\n  <span style=\"color: #0000ff;\">auto<\/span> distPerWeek2= 4*workPerDay-3*abbrevationToWork+ 2*workout;\r\n  <span style=\"color: #0000ff;\">auto<\/span> distPerWeek3= 4*workout + 2*shopping;\r\n  <span style=\"color: #0000ff;\">auto<\/span> distPerWeek4= 5*workout + shopping;\r\n  \r\n  <span style=\"color: #0000ff;\">auto<\/span> averageDistance= getAverageDistance({distPerWeek1,distPerWeek2,distPerWeek3,distPerWeek4});\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"averageDistance: \"<\/span> &lt;&lt; averageDistance &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>How can I massively improve the program? Relatively easy by using <span style=\"font-family: courier new,courier;\">constexpr.<\/span> My key idea is to declare all instances of MyDistance in the main program as <span style=\"font-family: courier new,courier;\">constexpr.<\/span> Therefore, I say to the compiler: Instantiate the objects at compile time. But the compiler can only perform its job if the instantiation is based on constant expressions. I will get a compiler error if the compiler can not do it.<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n61\r\n62\r\n63\r\n64\r\n65\r\n66\r\n67\r\n68\r\n69\r\n70\r\n71\r\n72\r\n73\r\n74\r\n75\r\n76\r\n77\r\n78\r\n79\r\n80\r\n81<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ userdefinedLiteralsConstexpr.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">namespace<\/span> Distance{\r\n\r\n  <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyDistance<\/span>{\r\n    public:\r\n      constexpr MyDistance(<span style=\"color: #2b91af;\">double<\/span> i):m(i){}\r\n\r\n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>+(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; b){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m + b.m);\r\n      }\r\n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>-(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a,<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; b){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m - b.m);\r\n      }\r\n\t  \r\n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>*(<span style=\"color: #2b91af;\">double<\/span> m, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(m*a.m);\r\n      }\r\n\t  \r\n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>\/(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a, <span style=\"color: #2b91af;\">int<\/span> n){\r\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m\/n);\r\n      }\r\n\t  \r\n      <span style=\"color: #0000ff;\">friend<\/span> std::ostream&amp; <span style=\"color: #0000ff;\">operator<\/span>&lt;&lt; (std::ostream &amp;out, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; myDist){\r\n        out &lt;&lt; myDist.m &lt;&lt; <span style=\"color: #a31515;\">\" m\"<\/span>;\r\n        <span style=\"color: #0000ff;\">return<\/span> out;\r\n      }\r\n    private:<br \/>      <span style=\"color: #2b91af;\">double<\/span> m;\t  \r\n  };\r\n\r\n  <span style=\"color: #0000ff;\">namespace<\/span> Unit{\r\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _km(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> d){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(1000*d);\r\n    }\r\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _m(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> m){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(m);\r\n    }\r\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _dm(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> d){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(d\/10);\r\n    }\r\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _cm(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> c){\r\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(c\/100);\r\n    }\r\n  }\r\n  \r\n}\r\n  \r\nconstexpr Distance::MyDistance getAverageDistance(std::initializer_list&lt;Distance::MyDistance&gt; inList){\r\n  <span style=\"color: #0000ff;\">auto<\/span> sum= Distance::MyDistance{0.0};\r\n  <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #0000ff;\">auto<\/span> i: inList) sum = sum + i ;\r\n  <span style=\"color: #0000ff;\">return<\/span> sum\/inList.size(); \r\n}\r\n\r\n\r\n<span style=\"color: #0000ff;\">using<\/span> <span style=\"color: #0000ff;\">namespace<\/span> Distance::Unit;\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std:: cout &lt;&lt; std::endl;\r\n  \r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> work= 63.0_km;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> workPerDay= 2 * work;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> abbrevationToWork= 5400.0_m;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> workout= 2 * 1600.0_m;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> shopping= 2 * 1200.0_m;\r\n  \r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek1= 4*workPerDay-3*abbrevationToWork+ workout+ shopping;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek2= 4*workPerDay-3*abbrevationToWork+ 2*workout;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek3= 4*workout + 2*shopping;\r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek4= 5*workout + shopping;\r\n  \r\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> averageDistance= getAverageDistance({distPerWeek1,distPerWeek2,distPerWeek3,distPerWeek4});\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"averageDistance: \"<\/span> &lt;&lt; averageDistance &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The result of the calculation is not so exciting. To compile the program, I have to use a C++14 compiler. A current GCC of clang is fine. The current <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/hh567368.aspx#cpp14tabl\">Microsoft Visual 2015 C++-Compiler<\/a> supports only C++11. Therefore, <span style=\"font-family: courier new,courier;\">cl.exe<\/span> will not compile the function <span style=\"font-family: courier new,courier;\">getAverageDistance<\/span>. In C++11, a <span style=\"font-family: courier new,courier;\">constexpr<\/span> function can only have a return statement.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5022\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexprResult.png\" alt=\"userdefinedLiteralsConstexprResult\" width=\"572\" height=\"180\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexprResult.png 572w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexprResult-300x94.png 300w\" sizes=\"auto, (max-width: 572px) 100vw, 572px\" \/><\/p>\n<p>But it is very exciting to look at the assembler instructions. To simplify my job, I use the interactive compiler hosted on <a href=\"https:\/\/gcc.godbolt.org\/\">https:\/\/gcc.godbolt.org\/. <\/a>Have I already mentioned that I like this tool very much?<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5023\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexpr.png\" alt=\"userdefinedLiteralsConstexpr\" width=\"924\" height=\"700\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexpr.png 924w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexpr-300x227.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedLiteralsConstexpr-768x582.png 768w\" sizes=\"auto, (max-width: 924px) 100vw, 924px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>How should we interpret the results? Quite easy. In the main program (lines 64 &#8211; 75) defined constant expressions are part of the assembler program. Or to say it differently. <strong>All calculations are done at compile time.<\/strong> At run time, the program consists only of the already calculated expressions. That is an extremely easy job for the run time.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>So, that&#8217;s enough to make you keen on more. The details will follow in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/constexpr-variables-and-objects\">next post.<\/a> I will look deeper into <span style=\"font-family: courier new,courier;\">constexpr<\/span> variables, functions, and user-defined types. You have to keep a few rules in mind. Firstly, C++14 <span style=\"font-family: courier new,courier;\">constexpr<\/span> functions are more powerful than C++11<span id=\"transmark\"><\/span> <span style=\"font-family: courier new,courier;\">constexpr<\/span> functions. Secondly, you can execute <span style=\"font-family: courier new,courier;\">constexpr<\/span> functions at run time. Lastly, there are a few restrictions for user-defined types to instantiate them at compile time.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/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>You can define with the keyword constexpr an expression that can be evaluated at compile time. constexpr can be used for variables, functions, and user-defined types. An expression that is evaluated at compile time has a lot of advantages. For example, constexpr variables and instances of user-defined types are automatically thread-safe and can be stored [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":5022,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[428],"class_list":["post-5024","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-constexpr"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5024","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=5024"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5024\/revisions"}],"predecessor-version":[{"id":6927,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5024\/revisions\/6927"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5022"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}