{"id":5067,"date":"2016-12-11T06:11:51","date_gmt":"2016-12-11T06:11:51","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/std-shared-ptr\/"},"modified":"2023-06-26T12:32:57","modified_gmt":"2023-06-26T12:32:57","slug":"std-shared-ptr","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/std-shared-ptr\/","title":{"rendered":"std::shared_ptr"},"content":{"rendered":"<p><span style=\"font-family: courier new,courier;\">std::shared_ptr&#8217;<\/span>s share the resource. The shared reference counter counts the number of owners. Copying a&nbsp;<span style=\"font-family: courier new,courier;\">std::shared_ptr <\/span> increases the reference count by one. Destroying a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> decreases the reference count by one. If the reference count becomes zero, the resource will automatically be released.&nbsp;<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p>Before I deal with the details of the <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span>, I will bring you on the same page and explain the basics.<\/p>\n<p>&nbsp;<\/p>\n<h2>The Basics<\/h2>\n<p>Copying a<span style=\"font-family: courier new,courier;\"> std::shared_ptr<\/span> increases the reference count by one. Both smart pointers use the same resource afterwards. I depicted this scenario.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5064\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr.jpg\" alt=\"sharedPtr\" width=\"600\" height=\"341\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr.jpg 829w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr-300x170.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr-768x436.jpg 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Thanks to <span style=\"font-family: courier new,courier;\">shared1 shared2<\/span> are initialized. Ultimately, the reference count is 2, and both smart pointers have the same resource.<\/p>\n<h3>The application<\/h3>\n<p>The program shows the typical usage of smart pointers. To get a visual idea of the life cycle of the resource, I put a short message in the constructor and destructor of <span style=\"font-family: courier new,courier;\">MyInt<\/span> (lines 8 &#8211; 16).<\/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<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ sharedPtr.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;memory&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">using<\/span> std::shared_ptr;\r\n\r\n<span style=\"color: #0000ff;\">struct<\/span> MyInt{\r\n  MyInt(<span style=\"color: #2b91af;\">int<\/span> v):val(v){\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"  Hello: \"<\/span> &lt;&lt; val &lt;&lt; std::endl;\r\n  }\r\n  ~MyInt(){\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"  Good Bye: \"<\/span> &lt;&lt; val &lt;&lt; std::endl;\r\n  }\r\n  <span style=\"color: #2b91af;\">int<\/span> val;\r\n};\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  shared_ptr&lt;MyInt&gt; sharPtr(<span style=\"color: #0000ff;\">new<\/span> MyInt(1998));\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"    My value: \"<\/span> &lt;&lt; sharPtr-&gt;val &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sharedPtr.use_count(): \"<\/span> &lt;&lt; sharPtr.use_count() &lt;&lt; std::endl;\r\n\r\n\r\n  {\r\n    shared_ptr&lt;MyInt&gt; locSharPtr(sharPtr);\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"locSharPtr.use_count(): \"<\/span> &lt;&lt; locSharPtr.use_count() &lt;&lt; std::endl;\r\n  }\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sharPtr.use_count(): \"<\/span>&lt;&lt;  sharPtr.use_count() &lt;&lt; std::endl;\r\n\r\n  shared_ptr&lt;MyInt&gt; globSharPtr= sharPtr;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sharPtr.use_count(): \"<\/span>&lt;&lt;  sharPtr.use_count() &lt;&lt; std::endl;\r\n  globSharPtr.reset();\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"sharPtr.use_count(): \"<\/span>&lt;&lt;  sharPtr.use_count() &lt;&lt; std::endl;\r\n\r\n  sharPtr= shared_ptr&lt;MyInt&gt;(<span style=\"color: #0000ff;\">new<\/span> MyInt(2011));\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>Here is the screenshot of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5065\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr.png\" alt=\"sharedPtr\" style=\"margin: 15px;\" width=\"385\" height=\"318\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr.png 385w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr-300x248.png 300w\" sizes=\"auto, (max-width: 385px) 100vw, 385px\" \/>&nbsp;<\/p>\n<p>I create in line 22<span style=\"font-family: courier new,courier;\"> MyInt(1998). <\/span>This is the resource the smart pointer should take care of. By using <span style=\"font-family: courier new,courier;\">sharPtr-&gt;val<\/span> I have direct access to the resource (line 23). The output of the program shows the numbers of the reference counter. It starts in line 24 with one, becomes by the local copy <span style=\"font-family: courier new,courier;\">shartPtr<\/span> in line 28 two, and goes after the block (lines 27 &#8211; 40) back to one. As a reset call, the copy assignment in line 33 modifies the reference counter. The expression <span style=\"font-family: comic sans ms,sans-serif;\"><span style=\"font-family: courier new,courier;\">sharPtr= shared_ptr&lt;MyInt&gt;(new MyInt(2011))<\/span> <\/span><span style=\"font-family: comic sans ms,sans-serif;\">i<\/span>n line 38 is more interesting. Firstly, the resource <span style=\"font-family: comic sans ms,sans-serif;\"><span style=\"font-family: courier new,courier;\">MyInt(2011)<\/span><\/span> is created and assigned to<span style=\"font-family: comic sans ms,sans-serif;\"> <\/span><span style=\"font-family: comic sans ms,sans-serif;\"><span style=\"font-family: courier new,courier;\">sharPtr.<\/span><\/span> Consequently, the destructor of <span style=\"font-family: courier new,courier;\">sharPtr<\/span> is invoked. <span style=\"font-family: courier new,courier;\">sharedPtr<\/span> was the exclusive owner of the resource <span style=\"font-family: comic sans ms,sans-serif;\"><span style=\"font-family: courier new,courier;\">new MyInt(1998)<\/span> (line<\/span> 22). The last resource <span style=\"font-family: comic sans ms,sans-serif;\"><span style=\"font-family: courier new,courier;\">new MyInt(2011)<\/span>, <\/span>will be destroyed at the end of the main.<\/p>\n<p>The program should not be too challenging. Now we can dig deeper.<\/p>\n<h3>The control block<\/h3>\n<p>The <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span>&#8216;s share is more than a resource and a reference counter. They share a resource and a control block. The control block has two counters and, eventually, more data. Two counters? The control block has a counter for the <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> and the <span style=\"font-family: courier new,courier;\">std::weak_ptr <\/span>referencing the <span style=\"font-family: courier new,courier;\">std::shared_ptr.<\/span> That&#8217;s the first time I&#8217;m speaking about the <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span>. Their job is to break cyclic references. I will write a separate post about cyclic references. Once more, the overview.<span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p>The control block has<\/p>\n<ul>\n<li>a counter for the <span style=\"font-family: courier new,courier;\">std::shared_ptr.<\/span><\/li>\n<li>a counter for the <span style=\"font-family: courier new,courier;\">std::weak_ptr.<\/span><\/li>\n<li>eventually further data like a special deleter or an allocator.<\/li>\n<\/ul>\n<p>If you create s<span style=\"font-family: courier new,courier;\">td::shared_ptr<\/span> together with its resource, two allocations are necessary. One for the resource and one for the control block. <span style=\"font-family: courier new,courier;\">std::make_shared<\/span> makes one allocation out of the two and is, therefore, faster (see: <a href=\"https:\/\/www.modernescpp.com\/index.php\/memory-and-performance-overhead-of-smart-pointer\">Memory and performance overhead of smart pointers<\/a>) and safe. You do not have this safety guarantee for<span style=\"font-family: courier new,courier;\"> std::shared_ptr&lt;int&gt;(new int(2011)).<\/span> If you create a smart pointer with <span style=\"font-family: courier new,courier;\">std::shared_ptr&lt;int&gt;(new int(2011))<\/span>, one of the allocations may fail, and you have a memory leak.<\/p>\n<p>A special deleter can parametrize the std::shared_ptr. Exactly that happens in the next section of this post.<\/p>\n<\/p>\n<h2>The deleter<\/h2>\n<p>The deleter of the <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> is opposite to that of a <a href=\"https:\/\/www.modernescpp.com\/index.php\/blog\/std-unique-ptr\"><span style=\"font-family: courier new,courier;\">std::unique_ptr<\/span>, <\/a>not a component of the type<span style=\"font-family: courier new,courier;\">.<\/span> Therefore, you can easily push <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> with different deleters onto a <span style=\"font-family: courier new,courier;\">std::vector&lt;std::shared_ptr&lt;int&gt;&gt;<\/span>. The special deleter will be stored in the control block.<span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p>I create in the next example a special <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> that logs how much memory has already been released.<\/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<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ sharedPtrDeleter.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;memory&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;random&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;typeinfo&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">Deleter<\/span>{\r\npublic:\r\n  <span style=\"color: #2b91af;\">void<\/span> <span style=\"color: #0000ff;\">operator<\/span>()(T *ptr){\r\n    ++Deleter::count;\r\n    <span style=\"color: #0000ff;\">delete<\/span> ptr;\r\n  }\r\n  <span style=\"color: #2b91af;\">void<\/span> getInfo(){\r\n    std::string typeId{<span style=\"color: #0000ff;\">typeid<\/span>(T).name()};\r\n    <span style=\"color: #2b91af;\">size_t<\/span> sz= Deleter::count * <span style=\"color: #0000ff;\">sizeof<\/span>(T);\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"Deleted \"<\/span> &lt;&lt; Deleter::count &lt;&lt; <span style=\"color: #a31515;\">\" objects of type: \"<\/span> &lt;&lt; typeId &lt;&lt; std::endl;\r\n    std::cout &lt;&lt;<span style=\"color: #a31515;\">\"Freed size in bytes: \"<\/span>  &lt;&lt; sz &lt;&lt; <span style=\"color: #a31515;\">\".\"<\/span> &lt;&lt;  std::endl;\r\n    std::cout &lt;&lt; std::endl;\r\n  }\r\nprivate:\r\n  <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #2b91af;\">int<\/span> count;\r\n};\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\n<span style=\"color: #2b91af;\">int<\/span> Deleter&lt;T&gt;::count=0;\r\n\r\n<span style=\"color: #0000ff;\">typedef<\/span> Deleter&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; IntDeleter;\r\n<span style=\"color: #0000ff;\">typedef<\/span> Deleter&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; DoubleDeleter;\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> createRandomNumbers(){\r\n\r\n  std::random_device seed;\r\n\r\n  std::mt19937 engine(seed());\r\n\r\n  std::uniform_int_distribution&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; thousand(1,1000);\r\n  <span style=\"color: #2b91af;\">int<\/span> ranNumber= thousand(engine);\r\n  <span style=\"color: #0000ff;\">for<\/span> ( <span style=\"color: #2b91af;\">int<\/span> i=0 ; i &lt;= ranNumber; ++i) std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(<span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #2b91af;\">int<\/span>(i),IntDeleter());\r\n\r\n}\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  {\r\n    std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; sharedPtr1( <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #2b91af;\">int<\/span>,IntDeleter() );\r\n    std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; sharedPtr2( <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #2b91af;\">int<\/span>,IntDeleter() );\r\n    <span style=\"color: #0000ff;\">auto<\/span> intDeleter= std::get_deleter&lt;IntDeleter&gt;(sharedPtr1);\r\n    intDeleter-&gt;getInfo();\r\n    sharedPtr2.reset();\r\n    intDeleter-&gt;getInfo();\r\n\r\n  }\r\n  createRandomNumbers();\r\n  IntDeleter().getInfo();\r\n\r\n  {\r\n    std::unique_ptr&lt;<span style=\"color: #2b91af;\">double<\/span>,DoubleDeleter &gt; uniquePtr( <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #2b91af;\">double<\/span>, DoubleDeleter() );\r\n    std::unique_ptr&lt;<span style=\"color: #2b91af;\">double<\/span>,DoubleDeleter &gt; uniquePtr1( <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #2b91af;\">double<\/span>, DoubleDeleter() );\r\n    std::shared_ptr&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; sharedPtr( <span style=\"color: #0000ff;\">new<\/span> <span style=\"color: #2b91af;\">double<\/span>, DoubleDeleter() );\r\n\r\n    std::shared_ptr&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; sharedPtr4(std::move(uniquePtr));\r\n    std::shared_ptr&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; sharedPtr5= std::move(uniquePtr1);\r\n    DoubleDeleter().getInfo();\r\n  }\r\n\r\n  DoubleDeleter().getInfo();\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new,courier;\">Deleter<\/span> in lines 8 &#8211; 27 is the special deleter. The type T. parametrizes the deleter It counts with the static variable <span style=\"font-family: courier new,courier;\">count<\/span> (line 23), how often the call operator (lines 11 &#8211; 14) was used. Deleter returns all the information with <span style=\"font-family: courier new,courier;\">getInfo<\/span> (lines 15 &#8211; 21).&nbsp; The function <span style=\"font-family: courier new,courier;\">createRandomNumbers<\/span> (line 32 &#8211; 42) creates between 1 to 1000 <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> (line 40) parametrized by the special deleter <span style=\"font-family: courier new,courier;\">intDeleter().<\/span> <span style=\"font-family: courier new,courier;\"><\/span><span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p>The first usage of <span style=\"font-family: courier new,courier;\">intDeleter-&gt;getInfo()<\/span> shows that no resource has been released. This changes with the call <span style=\"font-family: courier new,courier;\">sharedPtr2.reset()<\/span> in line 53. An <span style=\"font-family: courier new,courier;\">int<\/span> variable with 4 bytes has been released. The call <span style=\"font-family: courier new,courier;\">createRandomNumbers() <\/span>in line 57 creates 74 <span style=\"font-family: courier new,courier;\">std::shared_ptr&lt;int&gt;.<\/span> Of course, you can use the deleter for a<span style=\"font-family: courier new,courier;\"> <\/span><span style=\"font-family: courier new,courier;\">std::unique_ptr<\/span> (lines 60 &#8211; 68). The memory for the double objects will be released after the end of the block in line 68. <span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5066\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtrDeleter.png\" alt=\"sharedPtrDeleter\" width=\"442\" height=\"380\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtrDeleter.png 442w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtrDeleter-300x258.png 300w\" sizes=\"auto, (max-width: 442px) 100vw, 442px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p><span style=\"font-family: courier new,courier;\">std::shared_ptr <\/span>has a lot more to offer. You can create a <span style=\"font-family: courier new,courier;\">std:.shared_ptr<\/span> to an already existing object. <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> has minimum multithreading guarantees. But one question is still not answered. Should your function take a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by value or by reference? Get the answers in the<a href=\"https:\/\/www.modernescpp.com\/index.php\/specialities-of-std-shared-ptr\"> next post.<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>std::shared_ptr&#8217;s share the resource. The shared reference counter counts the number of owners. Copying a&nbsp;std::shared_ptr increases the reference count by one. Destroying a std::shared_ptr decreases the reference count by one. If the reference count becomes zero, the resource will automatically be released.&nbsp;<\/p>\n","protected":false},"author":21,"featured_media":5064,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[498,400,399],"class_list":["post-5067","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-memory","tag-shared_ptr","tag-smart-pointers"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5067","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=5067"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5067\/revisions"}],"predecessor-version":[{"id":6915,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5067\/revisions\/6915"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5064"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}