{"id":6343,"date":"2022-04-12T05:58:47","date_gmt":"2022-04-12T05:58:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/define-concepts\/"},"modified":"2023-06-26T09:08:40","modified_gmt":"2023-06-26T09:08:40","slug":"define-concepts","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/define-concepts\/","title":{"rendered":"Define Concepts"},"content":{"rendered":"<p>There are two ways to define a concept: You can combine existing concepts and compile-time predicates, or you can apply a requires expression in four different ways.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5808\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png\" alt=\"TimelineCpp20Concepts\" width=\"650\" height=\"255\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts.png 954w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-300x118.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/11\/TimelineCpp20Concepts-768x301.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Before I write about C++20 and Concepts, I want to remark briefly.<\/p>\n<h2>My Second Iteration Through C++20<\/h2>\n<p>I have written over 80 posts about<a href=\"https:\/\/www.modernescpp.com\/index.php\/category\/c-20\"> C++20<\/a> and 20 about<a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/concepts?start=0\"> Concepts<\/a>. My previous C++20 posts are one to three years old. This has two important implications. First, I learned, in the meantime, a lot of new stuff about C++20. Second, you don&#8217;t have my previous posts in mind. Consequentially, I provide so much content in these posts in my second iteration through C++20 that you can follow my explanation and provide links to my previous posts if necessary.<\/p>\n<p>Following this strategy, here is the general idea of concepts.<\/p>\n<\/p>\n<h2>Concepts<\/h2>\n<p>Generic programming with templates enables it to define functions and classes which can be used with various types. As a result, it is not uncommon for you to instantiate a template with the wrong type. The result can be many pages of cryptic error messages. This problem ends with concepts. Concepts empower you to write requirements for template parameters checked by the compiler and revolutionize how we think about and write generic code. Here is why:<\/p>\n<ul>\n<li>Requirements for template parameters become part of their public interface.<\/li>\n<li>The overloading of functions or specializations of class templates can be based on concepts.<\/li>\n<li>We get improved error messages because the compiler checks the defined template parameter requirements against the template arguments.<\/li>\n<\/ul>\n<p>Additionally, this is not the end of the story.<\/p>\n<ul>\n<li>You can use predefined concepts or define your own.<\/li>\n<li>The usage of auto and concepts is unified. Instead of auto, you can use a concept.<\/li>\n<li>If a function declaration uses a concept, it automatically becomes a function template. Writing function templates is, therefore, as easy as writing a function.<\/li>\n<\/ul>\n<p>The following code snippet demonstrates the definition and the use of the straightforward concept <code>Integral<\/code>:<\/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;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Integral <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;<br \/>\r\nIntegral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #cc00ff;\">gcd<\/span>(Integral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> a, Integral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> b) {\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ) <span style=\"color: #006699; font-weight: bold;\">return<\/span> a;\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> <span style=\"color: #006699; font-weight: bold;\">return<\/span> gcd(b, a <span style=\"color: #555555;\">%<\/span> b);\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <code>Integral<\/code> concept requires from its type parameter<code> T<\/code> that <code>std::is_integral&lt;T&gt;::value<\/code> evaluates to true.<code> std::is_integral&lt;T&gt;::value<\/code> is a function from the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type traits library<\/a> checking at compile time if <code>T<\/code> is integral. If <code>std::is_integral&lt;T&gt;::value<\/code> evaluates to <code>true<\/code>, all is fine; otherwise, you get a compile-time error.<\/p>\n<p>The <code>gcd<\/code> algorithm determines the greatest common divisor based on the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Euclid\">Euclidean <\/a>algorithm. The code uses the so-called abbreviated function template syntax to define <code>gcd<\/code>. Here, gcd requires that its arguments and return type support the concept <code>Integral<\/code>. In other words, <code>gcd<\/code> is a function template that puts requirements on its arguments and return value. When I remove the syntactic sugar, you can see the nature of gcd.<br \/>The semantically equivalent <code>gcd<\/code> algorithm, using a <code>requires<\/code> clause.<\/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;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>                                  \r\nrequires Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>\r\nT gcd(T a, T b) {\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span>( b <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">0<\/span> ) <span style=\"color: #006699; font-weight: bold;\">return<\/span> a;\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #cc00ff;\">gcd<\/span>(b, a <span style=\"color: #555555;\">%<\/span> b);\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <code>requires<\/code> clause states the requirements on the type parameters of <code>gcd<\/code>.<\/p>\n<p>If you need more information about concepts, read the four following posts:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-details\">C++20: Concepts, the Details<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-the-placeholder-syntax\">C++20: Concepts, the Placeholder Syntax<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concept-syntactic-sugar\">C++20: Concepts &#8211; Syntactic Sugar<\/a><\/li>\n<li><a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-predefined-concepts\">C++20: Concepts &#8211; Predefined Concepts<\/a><\/li>\n<\/ul>\n<p>After this introduction, let me define concepts.<\/p>\n<h2>Define Concepts<\/h2>\n<div>\n<div>When the concept you are looking for is not one of the predefined concepts in C++20, you must define your concept. I will define a few concepts distinguishable from the predefined concepts through CamelCase syntax. Consequently, my concept for a signed integral is named <code>SignedIntegral<\/code>, whereas the C++ standard concept goes by the name <code>signed_integra<\/code>l.<\/div>\n<div>&nbsp;<\/div>\n<div>\n<div>\n<div>The syntax to define a concept is straightforward:<\/div>\n<\/div>\n<\/div>\n<div>&nbsp;<\/div>\n<\/div>\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;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">-<\/span>parameter<span style=\"color: #555555;\">-<\/span>list<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept concept<span style=\"color: #555555;\">-<\/span>name <span style=\"color: #555555;\">=<\/span> constraint<span style=\"color: #555555;\">-<\/span>expression;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<div>\n<div>A concept definition starts with the keyword <code>template<\/code> and has a template parameter list. The second line is more interesting. It uses the keyword <code>concept<\/code> followed by the concept name and the constraint expression.<\/div>\n<div>&nbsp;<\/div>\n<div>\n<div>\n<div>A <code>constraint-expression<\/code> is a compile-time predicate. A compile-time predicate is a function that runs at compile time and returns a boolean. This compile-time predicate can either be:<\/div>\n<p><\/p>\n<ul>\n<li>A logical combination of other concepts or compile-time predicates using conjunctions (<code>&amp;&amp;<\/code>), disjunctions (<code>||<\/code>), or negations <code>(!<\/code>)<\/li>\n<\/ul>\n<p><\/p>\n<ul>\n<li>A requires expression\n<ul>\n<li>Simple requirements<\/li>\n<li>Type requirements<\/li>\n<li>Compound requirements<\/li>\n<li>Nested requirements<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<div>Let me continue with the first variant:<\/div>\n<div>&nbsp;<\/div>\n<h3>A Logical Combination of other Concepts or Compile-Time Predicates<\/h3>\n<div>\n<div>You can combine concepts and compile-time predicates using conjunctions (<code>&amp;&amp;<\/code>) and disjunctions (<code>||<\/code>). You can negate components using the exclamation mark (<code>!<\/code>). Evaluation of this logical combination of concepts and compile-time predicates obeys short-circuit evaluation. Short circuit evaluation means that the evaluation of a logical expression automatically stops when its overall result is already determined.<\/div>\n<div>\n<div><\/p>\n<div>Thanks to the many compile-time predicates of the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type traits library<\/a>, you have all tools required to build powerful concepts at your disposal.<\/div>\n<div>&nbsp;<\/div>\n<div>\n<div>\n<div>Let&#8217;s start with the concepts <code>Integral<\/code>, <code>SignedIntegral<\/code>, and <code>UnsignedIntegral<\/code>. &nbsp;<\/div>\n<div>&nbsp;<\/div>\n<\/div>\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;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\nconcept Integral <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\nconcept SignedIntegral <span style=\"color: #555555;\">=<\/span> Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> std<span style=\"color: #555555;\">::<\/span>is_signed<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\nconcept UnsignedIntegral <span style=\"color: #555555;\">=<\/span> Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> <span style=\"color: #555555;\">!<\/span>SignedIntegral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>;\r\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div>&nbsp;<\/div>\n<div>I used the type-traits function std::is_integral to define the concept <code>Integral<\/code> (line 1). Thanks to the function std::is_signed, I refine the concepts <code>Integral<\/code> to the concept <code>SignedIntegral<\/code> (line 2). Finally, negating the concept <code>SignedIntegral<\/code> gives me the concept <code>UnsignedIntegral<\/code> (line 3). Okay, let&#8217;s try it out.<\/div>\n<div>&nbsp;<\/div>\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;\">\/\/ SignedUnsignedIntegrals.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Integral <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept SignedIntegral <span style=\"color: #555555;\">=<\/span> Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> std<span style=\"color: #555555;\">::<\/span>is_signed<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept UnsignedIntegral <span style=\"color: #555555;\">=<\/span> Integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> <span style=\"color: #555555;\">!<\/span>SignedIntegral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">func<\/span>(SignedIntegral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> integ) {               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"SignedIntegral: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> integ <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">func<\/span>(UnsignedIntegral <span style=\"color: #006699; font-weight: bold;\">auto<\/span> integ) {             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"UnsignedIntegral: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> integ <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\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    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    func(<span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>);\r\n    func(<span style=\"color: #ff6600;\">5u<\/span>);\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<div>\n<div>I use the abbreviated function-template syntax to overload the function <code>func<\/code> on the concept <code>SignedIntegral<\/code> (line 1) and <code>UnsignedIntegral<\/code> (line 2). Read more about the abbreviated function template syntax in my previous post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concept-syntactic-sugar\">C++20: Concepts &#8211; Syntactic Sugar<\/a>.&nbsp; The compiler chooses the expected overload:<\/div>\n<div>&nbsp;<\/div>\n<div><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6342\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/04\/signedUnsignedIntegrals.png\" alt=\"signedUnsignedIntegrals\" width=\"400\" height=\"203\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/04\/signedUnsignedIntegrals.png 466w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/04\/signedUnsignedIntegrals-300x152.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/div>\n<div>&nbsp;<\/div>\n<div>\n<div>\n<div>For completeness reasons, the following concept <code>Arithmetic<\/code> uses disjunction.<\/div>\n<div>&nbsp;<\/div>\n<\/div>\n<\/div>\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;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\nconcept Arithmetic <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>is_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">||<\/span> std<span style=\"color: #555555;\">::<\/span>is_floating_point<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n<\/pre>\n<\/div>\n<div>&nbsp;<\/div>\n<h2>What&#8217;s next?<\/h2>\n<div>I defined in this post the concepts <code>Integral<\/code>, <code>SignedIntegral<\/code>, and <code>UnsignedIntegral<\/code> using logical combinations of other concepts and compile-time predicates. In my next post, I will apply requires expressions to define concepts.<\/div>\n<div>&nbsp;<\/div>\n<div>&nbsp;<\/div>\n<div><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>There are two ways to define a concept: You can combine existing concepts and compile-time predicates, or you can apply a requires expression in four different ways.<\/p>\n","protected":false},"author":21,"featured_media":5808,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[415],"class_list":["post-6343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-concepts"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6343","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=6343"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6343\/revisions"}],"predecessor-version":[{"id":6673,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6343\/revisions\/6673"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5808"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}