{"id":5919,"date":"2020-06-02T17:44:51","date_gmt":"2020-06-02T17:44:51","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-20-open-questions-to-modules\/"},"modified":"2023-06-26T09:49:41","modified_gmt":"2023-06-26T09:49:41","slug":"c-20-open-questions-to-modules","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-20-open-questions-to-modules\/","title":{"rendered":"C++20: Further Open Questions to Modules"},"content":{"rendered":"<p>So far, I have written in my last four posts the basics you should know about modules in C++20. Only a few questions about modules are still open. In this post, I address these open questions, such as templates in modules, the linkage of modules, and header units.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5199\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/TimelineCpp20.png\" alt=\"TimelineCpp20\" width=\"650\" height=\"223\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/TimelineCpp20.png 894w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/TimelineCpp20-300x103.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/TimelineCpp20-768x265.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>I assume in this post that you know my previous posts to modules. If not, make yourself comfortable and read the following posts.<\/p>\n<ul>\n<li><a href=\"https:\/\/bit.ly\/cpp20-module\">C++20: The Advantages of Modules<\/a><\/li>\n<li><a href=\"https:\/\/bit.ly\/SimpleMathModul\">C++20: A Simple math Module<\/a><\/li>\n<li><a href=\"https:\/\/bit.ly\/ModuleInterfaceUnitModuleImplementationUnit\">C++20: Module Interface Unit and Module Implementation Unit<\/a><\/li>\n<li><a href=\"https:\/\/bit.ly\/DivideModules\">C++20: Structure Modules<\/a><\/li>\n<\/ul>\n<h2>Templates and Modules<\/h2>\n<p>I often hear the question: How do modules export templates? When you instantiate a template, its definitions must be available. This is the reason that template definitions are hosted in headers. Conceptually, the usage of templates has the following structure.<\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">templateSum.h<\/span><\/li>\n<\/ul>\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;\">\/\/ templateSum.h<\/span>\r\n&nbsp; <br \/><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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum(T fir, T2 sec) { \r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">+<\/span> sec;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">sumMain.cpp<\/span><\/li>\n<\/ul>\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;\">\/\/ sumMain.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;templateSum.h&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    sum(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">1.5<\/span>);\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <span style=\"font-family: 'courier new', courier;\">main program<\/span> directly includes the header <span style=\"font-family: courier new, courier;\">templateSum.h<\/span> into the program<span style=\"font-family: courier new, courier;\"> sumMain.cpp. <\/span>The call <span style=\"font-family: courier new, courier;\">sum(1, 1.5)<\/span> triggers the so-called template instantiation. In this case, the compiler generates the function sum out of the function template, which takes an <span style=\"font-family: courier new, courier;\">int<\/span> and a <span style=\"font-family: courier new, courier;\">double<\/span>. If you want to see this process live, play with the example on <a href=\"https:\/\/cppinsights.io\/s\/cee41fd8\">C++ Insights<\/a>.&nbsp; <span style=\"font-family: courier new, courier;\"> <\/span><\/p>\n<p>With C++20, templates can and should be in modules. Modules have a unique internal representation that is neither source code nor assembly. This representation is a kind of an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Abstract_syntax_tree\">abstract syntax tree<\/a> (AST). Thanks to this AST, the template definition is available during template instantiation.<\/p>\n<p>I define the function template sum in the module math in the following example.<\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">mathModuleTemplate.ixx<\/span><\/li>\n<\/ul>\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;\">\/\/ mathModuleTemplate.ixx<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">export<\/span> module math;    \r\n\r\n<span style=\"color: #006699; font-weight: bold;\">export<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> math {         \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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum(T fir, T2 sec) { \r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> fir <span style=\"color: #555555;\">+<\/span> sec;\r\n    }\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">clientTemplate.cpp<\/span><\/li>\n<\/ul>\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;\">\/\/ clientTemplate.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\nimport math;\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> std<span style=\"color: #555555;\">::<\/span>endl;     \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"math::sum(2000, 11): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> math<span style=\"color: #555555;\">::<\/span>sum(<span style=\"color: #ff6600;\">2000<\/span>, <span style=\"color: #ff6600;\">11<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"math::sum(2013.5, 0.5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> math<span style=\"color: #555555;\">::<\/span>sum(<span style=\"color: #ff6600;\">2013.5<\/span>, <span style=\"color: #ff6600;\">0.5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"math::sum(2017, false): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> math<span style=\"color: #555555;\">::<\/span>sum(<span style=\"color: #ff6600;\">2017<\/span>, <span style=\"color: #336666;\">false<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The command line to compile the program is not different from the previous one in the post &#8220;<a href=\"https:\/\/bit.ly\/DivideModules\">C++20: Structure Modules&#8221;.<\/a> Consequently, I skip it and present the output of the program directly:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5917\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate.png\" alt=\"clientTemplate\" width=\"350\" height=\"167\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate.png 1170w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate-300x143.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate-1024x489.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate-768x367.png 768w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/p>\n<p>With modules, we get a new kind of linkage:<\/p>\n<\/p>\n<h2>Module Linkage<\/h2>\n<p>So far, C++ supports two kinds of linkage: internal and external.<\/p>\n<ul>\n<li><strong>Internal linkage<\/strong>: Names with internal linkage are not accessible outside the translation unit. The internal linkage includes mainly namespace-scope names declared static and anonymous namespaces members.<\/li>\n<li><strong>External linkage<\/strong>. Names with external linkage are accessible outside the translation unit. The external linkage includes names declared not as static, class types, and their members, variables, and templates.<\/li>\n<\/ul>\n<p>Modules introduce module linkage:<\/p>\n<ul>\n<li><strong>Module linkage<\/strong>: Names within module linkage are only accessible inside the module. Names have module linkage if they don&#8217;t have internal linkage and are not exported.<\/li>\n<\/ul>\n<p>A small variation of the previous module <span style=\"font-family: courier new, courier;\">math <\/span>makes my point. Imagine I want to return the user of my function template <span style=\"font-family: courier new, courier;\">sum <\/span>additionally<span style=\"font-family: courier new, courier;\">,<\/span>&nbsp;which type the compiler deduces as the return type.<span style=\"font-family: courier new, courier;\"><\/span><\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">mathModuleTemplate1.ixx<\/span><\/li>\n<\/ul>\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;\">\/\/ mathModuleTemplate1.ixx<\/span>\r\n\r\nmodule;\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;typeinfo&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">export<\/span> module math;   \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;\">\/\/ (2)<\/span> &nbsp;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> showType(T<span style=\"color: #555555;\">&amp;&amp;<\/span> t) {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #006699; font-weight: bold;\">typeid<\/span>(std::forward&lt;T&gt;(t)).name();\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">export<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> math {                             <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/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: #006699; font-weight: bold;\">typename<\/span> T2<span style=\"color: #555555;\">&gt;<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum(T fir, T2 sec) {\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> res <span style=\"color: #555555;\">=<\/span> fir <span style=\"color: #555555;\">+<\/span> sec;\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>make_pair(res, showType(res)); <span style=\"color: #0099ff; font-style: italic;\"> \/\/ (1)<\/span> \r\n    }\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Instead of the sum of the numbers, the function template sum returns a <span style=\"font-family: courier new, courier;\">std::pair<\/span> (1) consisting of the sum and a string representation of the type <span style=\"font-family: courier new, courier;\">res<\/span>. I put the function template <span style=\"font-family: courier new, courier;\">showType<\/span> (2) not in the exporting namespace math (3). Consequently, invoking it from outside the module <span style=\"font-family: courier new, courier;\">math<\/span> is not possible. <span style=\"font-family: courier new, courier;\">showType<\/span> uses <a href=\"https:\/\/www.modernescpp.com\/index.php\/perfect-forwarding\">perfect forwarding<\/a> to preserve the value categories of the function argument <span style=\"font-family: courier new, courier;\">t<\/span>. The function <span style=\"font-family: courier new, courier;\">typeid<\/span> queries information about the type at run-time (<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\">runtime type identification (RTTI)<\/a>).<\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">clientTemplate1.cpp<\/span><\/li>\n<\/ul>\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;\">\/\/ clientTemplate1.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\nimport math;\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> std<span style=\"color: #555555;\">::<\/span>endl;     \r\n   \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> [val, message] <span style=\"color: #555555;\">=<\/span> math<span style=\"color: #555555;\">::<\/span>sum(<span style=\"color: #ff6600;\">2000<\/span>, <span style=\"color: #ff6600;\">11<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"math::sum(2000, 11): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> val <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; type: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> [val1, message1] <span style=\"color: #555555;\">=<\/span>  math<span style=\"color: #555555;\">::<\/span>sum(<span style=\"color: #ff6600;\">2013.5<\/span>, <span style=\"color: #ff6600;\">0.5<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"math::sum(2013.5, 0.5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> val1 <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; type: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message1 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> [val2, message2] <span style=\"color: #555555;\">=<\/span>  math<span style=\"color: #555555;\">::<\/span>sum(<span style=\"color: #ff6600;\">2017<\/span>, <span style=\"color: #336666;\">false<\/span>);\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"math::sum(2017, false): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> val2 <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"; type: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> message2 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the program displays the value of the summation and a string representation of the automatically deduced type.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5918\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate1.png\" alt=\"clientTemplate1\" width=\"400\" height=\"154\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate1.png 1450w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate1-300x116.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate1-1024x395.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/06\/clientTemplate1-768x297.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Neither the GCC compiler nor the Clang compiler supports the next feature, which may become one of the favorite features regarding modules.<\/p>\n<h2>Header Units<\/h2>\n<p>Header units are a smooth way to transition from headers to modules. You must replace the #<span style=\"font-family: courier new, courier;\">include<\/span> directive with a new <span style=\"font-family: courier new, courier;\">import<\/span> directive.<\/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: #009999;\">#include &lt;vector&gt;      =&gt; import &lt;vector&gt;;<\/span>\r\n<span style=\"color: #009999;\">#include \"myHeader.h\"  =&gt; import \"myHeader.h\"; <\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>First, <span style=\"font-family: courier new, courier;\">import<\/span> respects the same lookup rules as <span style=\"font-family: courier new, courier;\">include<\/span>. This means in the case of the quotes (<span style=\"font-family: courier new, courier;\">&#8220;myHeader.h&#8221;<\/span>), the lookup first searches in the local directory before it continues with the system search path.<\/p>\n<p>Second, this is way more than text replacement. In this case, the compiler generates something module-like from the import directive and treats the result as a module. The importing module statement gets all exportable names for the header. The exportable names include macros. Importing these synthesized header units is faster and comparable in speed to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Precompiled_header\">precompiled headers<\/a>.<\/p>\n<h3>One Drawback<\/h3>\n<p>There is one drawback with header units. Not all headers are importable. Which headers are importable is implementation-defined, but the C++ standard guarantees all standard library headers are importable. The ability to import excludes C headers. They are just wrapped in the <span style=\"font-family: courier new, courier;\">std<\/span> namespace. For example, &lt;<span style=\"font-family: courier new, courier;\">cstring<\/span>&gt; is the C++ wrapper for &lt;<span style=\"font-family: courier new, courier;\">string.h<\/span>&gt;. You can quickly identify the wrapped C header because the pattern is: <strong><span style=\"font-family: courier new, courier;\">xxx.h<\/span> <\/strong>becomes<strong><span style=\"font-family: courier new, courier;\"> cxxx.<\/span> <\/strong><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>With this post, I completed my story to modules, and, in particular, I completed my story to the big four in C++20. Here are all existing and upcoming posts to <a href=\"https:\/\/www.modernescpp.com\/index.php\/category\/c-20\">C++20.<\/a> With my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-the-three-way-comparison-operator\">next post<\/a>, I will have a closer look at the core language features in C++, which are not so prominent such as concepts or modules. I start with the three-way comparison operator.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So far, I have written in my last four posts the basics you should know about modules in C++20. Only a few questions about modules are still open. In this post, I address these open questions, such as templates in modules, the linkage of modules, and header units.<\/p>\n","protected":false},"author":21,"featured_media":5199,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[443],"class_list":["post-5919","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-modules"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5919","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=5919"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5919\/revisions"}],"predecessor-version":[{"id":6739,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5919\/revisions\/6739"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5199"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5919"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}