{"id":2596,"date":"2018-07-31T22:22:51","date_gmt":"2018-07-31T14:22:51","guid":{"rendered":"https:\/\/nodelay.xyz\/?p=2596"},"modified":"2018-07-31T22:22:51","modified_gmt":"2018-07-31T14:22:51","slug":"c-template-handle-mutual-circular-dependencies","status":"publish","type":"post","link":"https:\/\/dayandcarrot.space\/?p=2596","title":{"rendered":"C++ Template: Handle mutual (circular) dependencies"},"content":{"rendered":"<p>Sometimes we have two classes that need to call each other&#8217;s somewhat function, for example<\/p>\n<pre class=\"lang:c++ decode:true\">template &lt;typename A&gt;\nstruct B\n{\n    A* p_a_ = nullptr;\n};\ntemplate &lt;typename B&gt;\nstruct A\n{\n    B* p_b_ = nullptr;\n};<\/pre>\n<p>but as you can see A depends on B&#8217;s type to initialize and vise versa. If we declare the types as above we&#8217;ll not get a chance to create any instance.<br \/>\nThere are at least two ways to resolve the issue.<\/p>\n<h3>I.Template template<\/h3>\n<p>A quick introduction about template template can be found <a href=\"https:\/\/blog.feabhas.com\/2014\/08\/templates-of-templates\/\">here<\/a>.<br \/>\nDeclare either of {A, B} with template of template which accepts the other&#8217;s template argument.<\/p>\n<pre class=\"lang:c++ decode:true \">template &lt;template&lt;typename&gt; typename A_t&gt;\nstruct B\n{\n    using A = A_t&lt;B&gt;;\n    A* p_a_ = nullptr;\n};\ntemplate &lt;typename B&gt;\nstruct A\n{\n    B* p_b_ = nullptr;\n};\n\/\/and declare like this\nusing B_t = B&lt;A&gt;;\nB_t b_instance;\nA&lt;B_t&gt; A_instance;<\/pre>\n<h3>II.Type traits<\/h3>\n<p>The other resolution is create a type trait struct which acts like a bridge that links the type of each other.<\/p>\n<pre class=\"lang:c++ decode:true\">template &lt;typename foobar_tratis&gt;\nstruct foobar_notifier\n{\n\tusing inst_t = typename foobar_tratis::foobar_inst_t;\n\tinst_t* inst_ = nullptr;\n\tvoid foobar()\n\t{\n\t\tstd::cout &lt;&lt; \"foobar_notifier\" &lt;&lt; std::endl;\n\t}\n};\ntemplate &lt;typename foobar_tratis&gt;\nstruct foobar_inst\n{\n\tusing notifier_t = typename foobar_tratis::foobar_notifier_t;\n\tnotifier_t* notifier_ = nullptr;\n\tvoid foobar()\n\t{\n\t\tstd::cout &lt;&lt; \"foobar_inst\" &lt;&lt; std::endl;\n\t}\n};\nstruct foobar_tratis\n{\n\tusing foobar_notifier_t = foobar_notifier&lt;md_inst_traits&gt;;\n\tusing foobar_inst_t = foobar_inst&lt;md_inst_traits&gt;;\n};\n\/\/\/ and declare like this\nfoobar_inst&lt;foobar_tratis&gt; inst2;\nfoobar_notifier&lt;foobar_tratis&gt; notifier2;<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes we have two classes that need to call each other&#8217;s somewhat function, for example template &lt;typename A&gt; struct B { A* p_a_ = nullptr; }; template &lt;typename B&gt; struct A { B* p_b_ = nullptr; }; but as you can see A depends on B&#8217;s type to initialize and vise versa. If we declare [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[28,29],"class_list":["post-2596","post","type-post","status-publish","format-standard","hentry","category-study","tag-c","tag-c-template"],"_links":{"self":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/posts\/2596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2596"}],"version-history":[{"count":0,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/posts\/2596\/revisions"}],"wp:attachment":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}