{"id":6147,"date":"2021-05-27T20:22:12","date_gmt":"2021-05-27T20:22:12","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/surprise-included-inheritance-and-member-functions-of-class-templates\/"},"modified":"2021-05-27T20:22:12","modified_gmt":"2021-05-27T20:22:12","slug":"surprise-included-inheritance-and-member-functions-of-class-templates","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/surprise-included-inheritance-and-member-functions-of-class-templates\/","title":{"rendered":"Surprise Included: Inheritance and Member Functions of Class Templates"},"content":{"rendered":"<p>In my last post, &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/class-templates\">Class Templates<\/a>&#8220;, I presented the basics. Today, I may surprise you with the inheritance of class templates and the instantiation of member functions of class templates.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6140\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/ClassTemplate.png\" alt=\"ClassTemplate\" width=\"650\" height=\"388\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/ClassTemplate.png 917w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/ClassTemplate-300x179.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/ClassTemplate-768x459.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Here is the first surprise. At least, it was it for me.<\/p>\n<h2>Inherited Member Functions of Class Templates are not Available<\/h2>\n<p>Let&#8217;s start simple.<\/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;\">\/\/ inheritance.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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Base<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> func(){                    <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;\">\"func\\n\"<\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span>;\r\n    }\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Derived<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Base{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> callBase(){\r\n        func();                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    }\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> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n    Derived derived;\r\n    derived.callBase();              \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I implemented a class <span style=\"font-family: courier new, courier;\">Base<\/span> and <span style=\"font-family: courier new, courier;\">Derived<\/span>. <code>Derived<\/code> is public derived from <span style=\"font-family: courier new, courier;\">Base<\/span> and can, therefore, be used in its method <span style=\"font-family: courier new, courier;\">callBase<\/span> (line 2), the member function <span style=\"font-family: courier new, courier;\">func<\/span> from class <span style=\"font-family: courier new, courier;\">Base<\/span>. Okay, I have nothing to add to the output of the program.<span style=\"font-family: courier new, courier;\"><\/span><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5637\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/inheritance.png\" alt=\"inheritance\" width=\"350\" height=\"171\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/inheritance.png 419w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/inheritance-300x147.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/p>\n<p>Making <span style=\"font-family: courier new, courier;\">Base<\/span> a class template changes the behavior.<\/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;\">\/\/ templateInheritance.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\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Base<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> func(){                    <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;\">\"func\\n\"<\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span>;\r\n    }\r\n};\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\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Derived<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Base<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> callBase(){\r\n        func();                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    }\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> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n    Derived<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> derived;\r\n    derived.callBase();              \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I assume the compiler error may surprise you.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5638\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance1.png\" alt=\"templateInheritance1\" width=\"650\" height=\"209\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance1.png 824w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance1-300x96.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance1-768x247.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>The line &#8220;<span style=\"font-family: courier new, courier;\">there are no arguments to &#8216;func&#8217; that depend on a template parameter, so a declaration of &#8216;func&#8217; must be available<\/span>&#8221; from the error message gives the first hint. <span style=\"font-family: courier new, courier;\">func<\/span> is a so-called non-dependent name because its name does not depend on the template parameter<code> T<\/code>. Non-dependent names are looked up and bound at the point of the template definition. Consequently, the compiler does not look in the from T dependent base class <span style=\"font-family: courier new, courier;\">Base&lt;T&gt;<\/span>, and there is no name <span style=\"font-family: courier new, courier;\">func<\/span> available outside the class template. Only dependent names are looked up and bound at the point of template instantiation.<\/p>\n<p>This process is called <a href=\"https:\/\/stackoverflow.com\/questions\/7767626\/two-phase-lookup-explanation-needed\">Two Phase Lookup.<\/a> The first phase is, in particular, responsible for looking up non-dependent names; the second phase is responsible for looking up dependent names.<\/p>\n<p>There are three workarounds to extend the name lookup to the dependent base class. The following example uses all three.<\/p>\n<p>&nbsp;<\/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;\">\/\/ templateInheritance2.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\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Base<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">void<\/span> func1() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"func1()\\n\"<\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span>;\r\n  }\r\n  <span style=\"color: #007788; font-weight: bold;\">void<\/span> func2() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"func2()\\n\"<\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span>;\r\n  }\r\n  <span style=\"color: #007788; font-weight: bold;\">void<\/span> func3() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"func3()\\n\"<\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #555555;\"><\/span>;\r\n  }\r\n};\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\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Derived<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Base<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span>{\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  <span style=\"color: #006699; font-weight: bold;\">using<\/span> Base<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>func2;              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">callAllBaseFunctions<\/span>(){\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">-&gt;<\/span>func1();                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    func2();                         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    Base<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;::<\/span>func3();                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n\r\n  }\r\n};\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> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n  Derived<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> derived;\r\n  derived.callAllBaseFunctions();\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> '\\n'<span style=\"color: #555555;\"><\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ol>\n<li><strong>Make the name&nbsp;dependent<\/strong>: The call <span style=\"font-family: courier new, courier;\">this-&gt;func1<\/span> in line 1 is dependent because <span style=\"font-family: courier new, courier;\">this<\/span> is implicit dependent. The name lookup will consider, in this case, all base classes.<\/li>\n<li><strong>Introduce the name&nbsp;into the current scope:<\/strong> The expression <span style=\"font-family: courier new, courier;\">using Base&lt;T&gt;::func2<\/span> (line 2) introduces <span style=\"font-family: courier new, courier;\">func2<\/span> into the current scope.<\/li>\n<li><strong>Call the name&nbsp;fully qualified<\/strong>: Calling <span style=\"font-family: courier new, courier;\">func3<\/span> fully qualified (line 3) will break a virtual dispatch and may cause new surprises.<\/li>\n<\/ol>\n<p>Which option should you use? In general, I prefer the first option making <code>func1<\/code> dependent:<code> this-&gt;func1<\/code>. This solution does even work when you rename your base class.&nbsp;<\/p>\n<p>In the end, here is the output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5639\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance2.png\" alt=\"templateInheritance2\" width=\"400\" height=\"215\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance2.png 445w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/02\/templateInheritance2-300x161.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<\/p>\n<h2>Instantiation of Member Functions is Lazy<\/h2>\n<p>Lazy means the instantiation of a member function of a class template happens only when needed. Proof? Here we are.<\/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;\">\/\/ lazy.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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">T<\/span><span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Lazy{\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> func() { std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"func<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\"<\/span><span style=\"color: #cc3300;\">; }<\/span>\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">func2<\/span>(); <span style=\"color: #0099ff; font-style: italic;\">\/\/ not defined (1)<\/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  Lazy<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> lazy;\r\n  lazy.func();\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<p>&nbsp;<\/p>\n<p>Although the method <span style=\"font-family: courier new,courier;\">func2<\/span> () (1) of class <span style=\"font-family: courier new,courier;\">Lazy<\/span> is only declared but not defined, the compiler accepts the program. Because <span style=\"font-family: courier new,courier;\">func2,<\/span> a definition of the member function is not necessary. <span style=\"font-family: courier new,courier;\"><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5164\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/lazy.png\" alt=\"lazy\" width=\"343\" height=\"126\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>This laziness of the instantiation process of member functions has two interesting properties.<\/p>\n<h2>Save Resources<\/h2>\n<p>When you instantiate, for example, a class template&nbsp; <code>Array2<\/code> for various types, only the used member functions are instantiated. This laziness does not hold for a non-template class <code>Array1<\/code>. Let me show you an example on C++ Insights.<\/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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ lazyInstantiation.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;cstddef&gt; <\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Array1<\/span> { \r\n <span style=\"color: #006699; font-weight: bold;\">public<\/span><span style=\"color: #555555;\">:<\/span> \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> getSize() <span style=\"color: #006699; font-weight: bold;\">const<\/span> { \r\n      <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #ff6600;\">10<\/span>; \r\n } \r\n <span style=\"color: #006699; font-weight: bold;\">private<\/span><span style=\"color: #555555;\">:<\/span> \r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> elem[<span style=\"color: #ff6600;\">10<\/span>]; \r\n};\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, std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">size_t<\/span> N<span style=\"color: #555555;\">&gt;<\/span> \r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Array2<\/span> { \r\n <span style=\"color: #006699; font-weight: bold;\">public<\/span><span style=\"color: #555555;\">:<\/span> \r\n    std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">size_t<\/span> getSize() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> N;\r\n    }\r\n  <span style=\"color: #9999ff;\">private:<\/span> \r\n     T elem[N]; \r\n}; \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    Array1 arr;\r\n    \r\n    Array2<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">5<\/span><span style=\"color: #555555;\">&gt;<\/span> myArr1;\r\n    Array2<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #ff6600;\">5<\/span><span style=\"color: #555555;\">&gt;<\/span> myArr2;  <span style=\"color: #0099ff;\"> \/\/ (1)<\/span> \r\n    myArr2.getSize();           <span style=\"color: #0099ff;\">\/\/ (2) <\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;The member function <code>getSize()<\/code> of the class template<code> Array2<\/code> is only instantiated for <code>myArr2<\/code> (1). The call causes this instantiation <code>myArr2.getSize()<\/code> (2).<\/p>\n<p>&nbsp;<a href=\"https:\/\/cppinsights.io\/s\/451db374\">C++ Insights<\/a> shows the truth. The crucial lines in the following screenshot are lines 40 and 59.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6144\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/lazyInstantiation.png\" alt=\"lazyInstantiation\" width=\"500\" height=\"727\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/lazyInstantiation.png 450w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/lazyInstantiation-206x300.png 206w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<h3>Partial Usage of Class Templates<\/h3>\n<p>You can instantiate class templates with template arguments that do not support all member functions. When you don&#8217;t call those member functions, all is fine.<\/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: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ classTemplatePartial.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&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 style=\"color: #0099ff; font-style: italic;\">\/\/ (1) <\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Matrix <\/span>{\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> Matrix(std<span style=\"color: #555555;\">::<\/span>initializer_list<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> inList)<span style=\"color: #555555;\">:<\/span> data(inList) {}\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> printAll() <span style=\"color: #006699; font-weight: bold;\">const<\/span> {   <span style=\"color: #0099ff;\">\/\/ (2)<\/span>\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> d<span style=\"color: #555555;\">:<\/span> data) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> d <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n    }\r\n<span style=\"color: #9999ff;\">private:<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>T<span style=\"color: #555555;\">&gt;<\/span> data;\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    <span style=\"color: #006699; font-weight: bold;\">const<\/span> Matrix<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myMatrix1({<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>});\r\n    myMatrix1.printAll();  <span style=\"color: #0099ff;\"> \/\/ (3)<\/span> \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> Matrix<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> myMatrix2({<span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #ff6600;\">11<\/span>, <span style=\"color: #ff6600;\">12<\/span>, <span style=\"color: #ff6600;\">13<\/span>});\r\n    myMatrix2.printAll(); <span style=\"color: #0099ff;\"> \/\/ (4)<\/span> \r\n\r\n     std::cout &lt;&lt; <span style=\"color: #cc3300;\">\"\\n\\n\"<\/span>;     <br \/>\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> Matrix<span style=\"color: #555555;\">&lt;<\/span>Matrix<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&gt;<\/span> myMatrix3({myMatrix1, myMatrix2});\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ myMatrix3.printAll(); ERROR (5)<\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The class template <code>Matrix<\/code> (1) is intentionally simple. It has a type parameter<code> T,<\/code> that holds its data in a<code> std::vector<\/code>, and can be initialized by a <code>std::initalizer_list<\/code>. <code>Matrix<\/code> supports the member function<code> printAll()<\/code> to display all its members. (3) and (4) show its usage. The output operator is not overloaded for <code>Matrix<\/code> Consequently, I can create<code><\/code> <code>myMatrix3<\/code> having other Matrix objects as members, but I cannot display them.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6145\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartial.png\" alt=\"classTemplatePartial\" width=\"450\" height=\"239\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartial.png 483w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartial-300x159.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Enabling line 5 causes a pretty verbose error message of about 274 lines.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6146\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartialError.png\" alt=\"classTemplatePartialError\" width=\"650\" height=\"140\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartialError.png 826w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartialError-300x65.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2021\/05\/classTemplatePartialError-768x166.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>I will write about alias templates and template parameters in my next post.<\/p>\n<h2>Bad Marketing<\/h2>\n<p>I did a bad marketing job. A few people asked me in the last few days if my<a href=\"https:\/\/leanpub.com\/c20\"> C++20 book, published on LeanPub<\/a>, is available in physical form. Sure, since one month. Choose your preferred Amazon Marketplace.<\/p>\n<div>&nbsp;<\/p>\n<div class=\"o9v6fnle cxmmr5t8 oygrvhab hcukyx3x c1et5uql ii04i59q\">\n<div dir=\"auto\">US: <a href=\"https:\/\/l.facebook.com\/l.php?u=https%3A%2F%2Fwww.amazon.com%2Fdp%2FB09328NKXK%3Ffbclid%3DIwAR2Fp0FfhsSAuvH6UsT7F2-V6O4qFS3ObSvILOWBV2PFhR672XGwV8gVzfA&amp;h=AT2WV7jjRhPwISE_2yyykZ9X_uxPoyYnouvPwl3TyyyTZOKqcIZrfXl2NsTqJZHxAl9qUWMwVZsZxMhQc25dfKDOIWC5fW0zFgqN5GyLGwvlR4eZGVJOK-emuzeLISWSxhFFv4-pIsMxeR81OOaH&amp;__tn__=-UK-R&amp;c[0]=AT3OG-dwUqRj29QUs0TDkMRMXOvNxgHeNRF6ryTojrqpQLOOB9H7mEhYJLKLyndBbsQ3-UBCI7dCrzyFmVLmhtmV6NxZXfA6c5jUEOX77mriNExfIwNLA7NBUIVhT5MpIfvW599Usga-kJMclXwv-bpDaqfMEPUobgCckGCPs5EHVFxSaiw30ydq1LzPEPzrmvhkB9lmS19BhW1ko5YqM8maFNq5kg\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.com\/dp\/B09328NKXK\">https:\/\/www.amazon.com\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">UK: <a href=\"https:\/\/l.facebook.com\/l.php?u=https%3A%2F%2Fwww.amazon.co.uk%2Fdp%2FB09328NKXK%3Ffbclid%3DIwAR10gK0iwxMsepQUONFFySP1hy1BuJN88vMMOMJ5tCWxqKs43Lpnm7sFAfw&amp;h=AT15ke2xNV1-t2NAXux-MXBankiOvgNdXvQcwtgWMGAX5H1WU7DiWzASNKUyVpkly8O5bHewKyDGMzKP1ypPLR1E3HJkcJf3MuF7QXkRZw-imoKycmTxuORdFDy64aQshirYlFx5AQWOn0CSnvyK&amp;__tn__=-UK-R&amp;c[0]=AT3OG-dwUqRj29QUs0TDkMRMXOvNxgHeNRF6ryTojrqpQLOOB9H7mEhYJLKLyndBbsQ3-UBCI7dCrzyFmVLmhtmV6NxZXfA6c5jUEOX77mriNExfIwNLA7NBUIVhT5MpIfvW599Usga-kJMclXwv-bpDaqfMEPUobgCckGCPs5EHVFxSaiw30ydq1LzPEPzrmvhkB9lmS19BhW1ko5YqM8maFNq5kg\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.co.uk\/dp\/B09328NKXK\">https:\/\/www.amazon.co.uk\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">DE: <a href=\"https:\/\/l.facebook.com\/l.php?u=https%3A%2F%2Fwww.amazon.de%2Fdp%2FB09328NKXK%3Ffbclid%3DIwAR2CsS3rvAPAP0M_BfeB-9o11Pzy4-4vf135_jJQXKkedVM4x6gakTC8tqg&amp;h=AT0Q9mcfkMMUdPZ3rvN8i_vSZ4n8e3c_KWLfWN1866gnnaqGoDm5ZUWI254-qkiEjWx6Sb1S6NeQixrPt05bAvEpAiXigE9bd75k0DXHUi7YPD05X1R4Oj4yQ2BACRIo3XIgiZqkTpjS3PWouyh2&amp;__tn__=-UK-R&amp;c[0]=AT3OG-dwUqRj29QUs0TDkMRMXOvNxgHeNRF6ryTojrqpQLOOB9H7mEhYJLKLyndBbsQ3-UBCI7dCrzyFmVLmhtmV6NxZXfA6c5jUEOX77mriNExfIwNLA7NBUIVhT5MpIfvW599Usga-kJMclXwv-bpDaqfMEPUobgCckGCPs5EHVFxSaiw30ydq1LzPEPzrmvhkB9lmS19BhW1ko5YqM8maFNq5kg\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.de\/dp\/B09328NKXK\">https:\/\/www.amazon.de\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">FR: <a href=\"https:\/\/l.facebook.com\/l.php?u=https%3A%2F%2Fwww.amazon.fr%2Fdp%2FB09328NKXK%3Ffbclid%3DIwAR3U44tOy647m_gYP-gyi-LoDliCyEYfI-GSCCMrL5T3DQ4sZRS12hAx9Uw&amp;h=AT17MTjwCtMuoll9XgnnV4afdDgRLwP4HsytOHo61WbMgKuGtWp4bNwNR16WCrKQhoJjsVHGKT-5dQ5vcmt1ElaZvvtrIsqZCz2LzJQV3ayZMEKg9Hq5BrQfgviA4ZRx_DjztgDJdKwn2sqYGgpG&amp;__tn__=-UK-R&amp;c[0]=AT3OG-dwUqRj29QUs0TDkMRMXOvNxgHeNRF6ryTojrqpQLOOB9H7mEhYJLKLyndBbsQ3-UBCI7dCrzyFmVLmhtmV6NxZXfA6c5jUEOX77mriNExfIwNLA7NBUIVhT5MpIfvW599Usga-kJMclXwv-bpDaqfMEPUobgCckGCPs5EHVFxSaiw30ydq1LzPEPzrmvhkB9lmS19BhW1ko5YqM8maFNq5kg\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.fr\/dp\/B09328NKXK\">https:\/\/www.amazon.fr\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">ES: <a href=\"https:\/\/l.facebook.com\/l.php?u=https%3A%2F%2Fwww.amazon.es%2Fdp%2FB09328NKXK%3Ffbclid%3DIwAR3iwadoVEtIxQM5QbRMf6GsbhAHoT8fxqLD-rQo_bvqmNdDFbeioCrk92A&amp;h=AT1tUA7bBDJFG-PO5Ig-863-dkmK15yevMBLpwbiCYskN_x8KRHtBxcnkczvG4yxU2v4XsaBU3p9ET0cmvCDJvix69PSLt_ah-K1D-COzxicB_TG4G2xKOl7m9jyQcZNlnUoapH7JbqGugu0WPQA&amp;__tn__=-UK-R&amp;c[0]=AT3OG-dwUqRj29QUs0TDkMRMXOvNxgHeNRF6ryTojrqpQLOOB9H7mEhYJLKLyndBbsQ3-UBCI7dCrzyFmVLmhtmV6NxZXfA6c5jUEOX77mriNExfIwNLA7NBUIVhT5MpIfvW599Usga-kJMclXwv-bpDaqfMEPUobgCckGCPs5EHVFxSaiw30ydq1LzPEPzrmvhkB9lmS19BhW1ko5YqM8maFNq5kg\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.es\/dp\/B09328NKXK\">https:\/\/www.amazon.es\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">IT: <a href=\"https:\/\/www.amazon.it\/dp\/B09328NKXK?fbclid=IwAR0crMx1YdflWY0YFhfTjDqYa0X0ysBr10MmUNle45B3wuuRD3vs75PqsgU\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.it\/dp\/B09328NKXK\">https:\/\/www.amazon.it\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">JP: <a href=\"https:\/\/www.amazon.co.jp\/dp\/B09328NKXK?fbclid=IwAR0crMx1YdflWY0YFhfTjDqYa0X0ysBr10MmUNle45B3wuuRD3vs75PqsgU\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.co.jp\/dp\/B09328NKXK\">https:\/\/www.amazon.co.jp\/dp\/B09328NKXK<\/a><\/div>\n<div dir=\"auto\">CA: <a href=\"https:\/\/www.amazon.ca\/dp\/B09328NKXK?fbclid=IwAR2_tLNS36VIOUAhu_180DCFOEUrKppWWWCS6Ev9oEnv-xbquFhSGqZNFrk\" target=\"_blank\" rel=\"nofollow noopener\" class=\"oajrlxb2 g5ia77u1 qu0x051f esr5mh6w e9989ue4 r7d6kgcz rq0escxv nhd2j8a9 nc684nl6 p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso i1ao9s8h esuyzwwr f1sip0of lzcic4wl py34i1dx gpro0wi8\" tabindex=\"0\" role=\"link\"><\/a><a href=\"https:\/\/www.amazon.ca\/dp\/B09328NKXK\">https:\/\/www.amazon.ca\/dp\/B09328NKXK<\/a><\/div>\n<div>&nbsp;<\/div>\n<div>&nbsp;<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, &#8220;Class Templates&#8220;, I presented the basics. Today, I may surprise you with the inheritance of class templates and the instantiation of member functions of class templates.<\/p>\n","protected":false},"author":21,"featured_media":6140,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[376],"tags":[],"class_list":["post-6147","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-templates"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6147","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=6147"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6147\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6140"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}