{"id":5831,"date":"2020-01-10T10:41:10","date_gmt":"2020-01-10T10:41:10","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-predefined-concepts\/"},"modified":"2023-06-26T09:56:18","modified_gmt":"2023-06-26T09:56:18","slug":"c-20-concepts-predefined-concepts","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-predefined-concepts\/","title":{"rendered":"C++20: Concepts &#8211; Predefined Concepts"},"content":{"rendered":"<p>C++20 has many predefined concepts. Consequentially, before you define your concept, you should know the existing ones. This post gives you an overview of the predefined concepts. To get a general idea of concepts, read my previous <a href=\"https:\/\/www.modernescpp.com\/index.php\/category\/c-20\">posts<\/a>.&nbsp;<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><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>Don&#8217;t reinvent the wheel. This golden rule also applies to concepts, by the way. The C++ Core Guidelines are very clear about this rule:&nbsp;<a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rt-std-concepts\">T.11: Whenever possible use standard concepts<\/a>.&nbsp;<\/p>\n<p>My information is from the newest C++20 draft: <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2019\/n4842.pdf\">N4842<\/a>. To find all predefined concepts is quite a job. Most concepts are in Chapter 18 (concepts library) and Chapter 24 (ranges library). Additionally, a few concepts are in Chapter 17 (language support library), chapter 20 (general utility library), chapter 23 (iterators library), and Chapter 26 (numerics library). The document also shows how the concepts are implemented.<\/p>\n<p>Honestly, I was astonished that I found no concept of concurrency such as <span style=\"font-family: 'courier new', courier;\">Lockable<\/span>. Initially, the concepts were written in CamelCase or Wiki syntax. Now, they are written with underscores. E.g., <span style=\"font-family: 'courier new', courier;\">DerivedFrom<\/span> became <span style=\"font-family: 'courier new', courier;\">derived_from<\/span>.<\/p>\n<p>Here are the concepts according to their ordering in the C++20 draft. I ignore this presentation the unique or auxiliary concepts. I also ignore the concepts from the ranges library. To understand them, you first have to understand the new ideas of the ranges library. I write about them when I write about the <a href=\"https:\/\/www.modernescpp.com\/index.php\/thebigfour\">ranges library<\/a>. The ranges library will follow the concepts immediately.&nbsp;<\/p>\n<p>I must warn you: if you don&#8217;t like technical posts, you probably don&#8217;t like this post.&nbsp;&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Language_support_library\"><\/span>Language support library<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This section has one interesting concept&nbsp;<span style=\"font-family: 'courier new', courier;\">three_way_comparable<\/span> to support the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-the-core-language\">three-way comparison operator<\/a>.&nbsp;<\/p>\n<p>If you want it more formal. Let <span style=\"font-family: 'courier new', courier;\">a<\/span> and <span style=\"font-family: 'courier new', courier;\">b<\/span> values of type <span style=\"font-family: 'courier new', courier;\">T<\/span>. They are essential&nbsp;<span style=\"font-family: 'courier new', courier;\">three_way_comparable<\/span> only if:<\/p>\n<ul>\n<li>(a &lt;=&gt; b == 0) == bool(a == b) is true,<\/li>\n<li>(a &lt;=&gt; b != 0) == bool(a != b) is true,<\/li>\n<li>((a &lt;=&gt; b) &lt;=&gt; 0) and (0 &lt;=&gt; (b &lt;=&gt; a)) are equal,<\/li>\n<li>(a &lt;=&gt; b &lt; 0) == bool(a &lt; b) is true,<\/li>\n<li>(a &lt;=&gt; b &gt; 0) == bool(a &gt; b) is true,<\/li>\n<li>(a &lt;=&gt; b &lt;= 0) == bool(a &lt;= b) is true,<\/li>\n<li>(a &lt;=&gt; b &gt;= 0) == bool(a &gt;= b) is true, and<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Concepts_Library\"><\/span>Concepts Library<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I assume these are the concepts we mainly use.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Language-related_concepts\"><\/span>Language-related concepts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This section has around 15 concepts that should be self-explanatory. These concepts express relationships between types, type classifications, and fundamental type properties. Their implementation is often directly based on the corresponding function from the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/type_traits\">type-traits library.<\/a> I rearranged them and added a few words if necessary.<\/p>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">same_as<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">derived_from<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">convertible_to<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">common_reference_with: common_reference_with&lt;T, U&gt;<\/span> must be well-formed, and <span style=\"font-family: 'courier new', courier;\">T<\/span> and <span style=\"font-family: 'courier new', courier;\">U<\/span> must be convertible to a reference type<span style=\"font-family: 'courier new', courier;\"> C<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">common_with: <\/span>similar t<span style=\"font-family: 'courier new', courier;\">o common_reference_with, <\/span>but the common type C has not to be a reference type<span style=\"font-family: 'courier new', courier;\"><\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">assignable_from<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">swappable<\/span><\/li>\n<\/ul>\n<h4>Arithmetic<\/h4>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">integral<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">signed_integral<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">unsigned_integral<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">floating_point<\/span><\/li>\n<\/ul>\n<p>Their definition is straightforward:&nbsp;<\/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;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept integral <span style=\"color: #555555;\">=<\/span> is_integral_v<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept signed_integral <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> is_signed_v<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept unsigned_integral <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>signed_integral<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept floating_point <span style=\"color: #555555;\">=<\/span> is_floating_point_v<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>;<\/pre>\n<\/div>\n<h4>Lifetime<\/h4>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">destructible<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">constructible_from<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">default_constructible<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">move_constructible<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">copy_constructible<\/span><\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Comparison_concepts\"><\/span>Comparison concepts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">boolean: <\/span>specifies if a type T is usable as a truth value; interestingly, pointers, smart pointers, and types with an explicit conversion operator to <span style=\"font-family: 'courier new', courier;\">bool<\/span> are not <span style=\"font-family: 'courier new', courier;\">boolean<\/span> types.<\/li>\n<li><span style=\"font-family: 'courier new', courier;\">equality_comparable<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">totally_ordered<\/span><\/li>\n<\/ul>\n<p>Maybe you know it from your math. For values <span style=\"font-family: 'courier new', courier;\">a, b<\/span>, and <span style=\"font-family: 'courier new', courier;\">c<\/span> of type <span style=\"font-family: 'courier new', courier;\">T, T<\/span> models <span style=\"font-family: 'courier new', courier;\">totally_ordered<\/span> only if<\/p>\n<ul>\n<li>Exactly one of bool(a &lt; b), bool(a &gt; b), or bool(a == b) is true.<\/li>\n<li>If bool(a &lt; b) and bool(b &lt; c), then bool(a &lt; c).<\/li>\n<li>bool(a &gt; b) == bool(b &lt; a).<\/li>\n<li>bool(a &lt;= b) == !bool(b &lt; a).<\/li>\n<li>bool(a &gt;= b) == !bool(a &lt; b).<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Object_concepts\"><\/span>Object concepts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">movable<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">copyable<\/span><\/li>\n<li>semiregular<\/li>\n<li>regular<\/li>\n<\/ul>\n<p>Here is the definition of the four concepts:<\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept movable <span style=\"color: #555555;\">=<\/span> is_object_v<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> move_constructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> assignable_from<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&amp;<\/span>, T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> swappable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept copyable <span style=\"color: #555555;\">=<\/span> copy_constructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> movable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> assignable_from<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&amp;<\/span>, <span style=\"color: #006699; font-weight: bold;\">const<\/span> T<span style=\"color: #555555;\">&amp;&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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept semiregular <span style=\"color: #555555;\">=<\/span> copyable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> default_constructible<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\nconcept regular <span style=\"color: #555555;\">=<\/span> semiregular<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #555555;\">&amp;&amp;<\/span> equality_comparable<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I have to add a few words. The concept <span style=\"font-family: 'courier new', courier;\">movable<\/span> requires for T that <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_object\">is_object_v&lt;T&gt;<\/a> holds. This means, under the hood, that T is either a scalar, an array, a union, or a class.&nbsp;<\/p>\n<p>I will implement the concept of&nbsp;<span style=\"font-family: 'courier new', courier;\">semiregular<\/span> and <span style=\"font-family: 'courier new', courier;\">regular<\/span> in future posts. Informally, a <span style=\"font-family: 'courier new', courier;\">semiregular<\/span> type behaves similarly to an <span style=\"font-family: 'courier new', courier;\">int<\/span>, and a <span style=\"font-family: 'courier new', courier;\">regular<\/span> type behaves similarly to an <span style=\"font-family: 'courier new', courier;\">int<\/span> and is comparable with <span style=\"font-family: 'courier new', courier;\">==.<\/span>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Callable_concepts\"><\/span>Callable concepts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">invocable<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">regular_invocable: F<\/span> models <span style=\"font-family: 'courier new', courier;\">invocable<\/span> and equality-preserving and does not modify the function arguments; equality-preserving means the <span style=\"font-family: 'courier new', courier;\">F<\/span> produces the same output when giving the same input<\/li>\n<li><span style=\"font-family: 'courier new', courier;\">predicate: F<\/span> models a <span style=\"font-family: 'courier new', courier;\">predicate<\/span> if <span style=\"font-family: 'courier new', courier;\">F<\/span> models <span style=\"font-family: 'courier new', courier;\">invocable <\/span>and returns a boolean<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"General_Utility_library\"><\/span>General Utility library<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This chapter has only special memory concepts; therefore, I skip it.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Iterators_library\"><\/span>Iterators library<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The iterators library has many important concepts. Here are the iterator categories:<\/p>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">input_iterator<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">output_iterator<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">forward_iterator<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">bidirectional_iterator<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">random_access_iterator<\/span><\/li>\n<li><span style=\"font-family: 'courier new', courier;\">contiguous_iterator<\/span><\/li>\n<\/ul>\n<p>The six categories of iterators correspond to the iterator concepts. The image shows the three most prominent iterator categories and the containers of the Standard Template Library, respectively.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5526\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories.png\" alt=\"IteratorCategories\" width=\"600\" height=\"362\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories.png 990w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories-300x181.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/10\/IteratorCategories-768x464.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>The following relation holds. A random-access iterator is a bidirectional iterator, and a bidirectional iterator is a forward iterator. A contiguous iterator is a random access iterator and requires that the elements of the container are stored contiguously in memory. This means <span style=\"font-family: 'courier new', courier;\">std::array, std::vector<\/span>, and <span style=\"font-family: 'courier new', courier;\">std::string<\/span> support contiguous iterators, but not <span style=\"font-family: 'courier new', courier;\">std::deque<\/span>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"_Algorithm_concepts\"><\/span>&nbsp;Algorithm concepts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><span style=\"font-family: 'courier new', courier;\">permutable: <\/span>reordering of elements in place is possible<\/li>\n<li><span style=\"font-family: 'courier new', courier;\">mergeable: <\/span>merging sorted sequences into an output sequence is possible<\/li>\n<li><span style=\"font-family: 'courier new', courier;\">sortable: <\/span>permuting a sequence into an ordered sequence is possible<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Numeric_library\"><\/span>Numeric library<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The numeric library has the concept of a&nbsp;<span style=\"font-family: 'courier new', courier;\">uniform_random_bit_generator<\/span>. A&nbsp;&nbsp;<span style=\"font-family: 'courier new', courier;\">uniform_random_bit_generator<\/span>&nbsp;g of type<span style=\"font-family: 'courier new', courier;\"> G<\/span> has to return unsigned integers so that each value is equally probable. Additionally, the uniform random bit generator <span style=\"font-family: 'courier new', courier;\">g<\/span> of type <span style=\"font-family: 'courier new', courier;\">G<\/span> has to support the member functions <span style=\"font-family: 'courier new', courier;\">G::min<\/span>, and <span style=\"font-family: 'courier new', courier;\">G::max<\/span>.<\/p>\n<p><span style=\"color: inherit; font-size: 35px;\">What&#8217;s next?<\/span><\/p>\n<p>With the<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-concepts-defining-concepts\"> next posts<\/a>, it becomes more practical. I write about the definition of concepts such as <span style=\"font-family: 'courier new', courier;\">integral,<\/span> <span style=\"font-family: 'courier new', courier;\">regular<\/span>, and <span style=\"font-family: 'courier new', courier;\">semiregular<\/span>. Defining concepts is more than just putting constraints on type parameters.&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>C++20 has many predefined concepts. Consequentially, before you define your concept, you should know the existing ones. This post gives you an overview of the predefined concepts. To get a general idea of concepts, read my previous posts.&nbsp;<\/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-5831","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\/5831","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=5831"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5831\/revisions"}],"predecessor-version":[{"id":6760,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5831\/revisions\/6760"}],"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=5831"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5831"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5831"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}