{"id":110895,"date":"2025-02-21T07:00:00","date_gmt":"2025-02-21T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110895"},"modified":"2025-02-21T07:34:24","modified_gmt":"2025-02-21T15:34:24","slug":"20250221-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250221-00\/?p=110895","title":{"rendered":"C++\/WinRT implementation inheritance: Notes on <CODE>winrt::implements<\/CODE>, part 3"},"content":{"rendered":"<p>In C++\/WinRT, the <code>implements<\/code> template type starts like this:<\/p>\n<pre>template &lt;typename D, typename... I&gt;\r\nstruct implements :\r\n    impl::producers&lt;D, I...&gt;,\r\n    impl::base_implements&lt;D, I...&gt;::type\r\n{\r\n<\/pre>\n<p>The <code>producers<\/code> template type generates the vtables for the COM interfaces. But that&#8217;s not what we&#8217;re looking at today. Today we&#8217;re going to look at the <code>base_<wbr \/>implements<\/code> part.<\/p>\n<p>The <code>base_<wbr \/>implements<\/code> type is defined as follows:<\/p>\n<pre>template &lt;typename D, typename Dummy = std::void_t&lt;&gt;, typename... I&gt;\r\nstruct base_implements_impl\r\n    : impl::identity&lt;root_implements&lt;D, I...&gt;&gt; {};\r\n\r\ntemplate &lt;typename D, typename... I&gt;\r\nstruct base_implements_impl&lt;D, std::void_t&lt;typename nested_implements&lt;I...&gt;::type&gt;, I...&gt;\r\n    : nested_implements&lt;I...&gt; {};\r\n\r\ntemplate &lt;typename D, typename... I&gt;\r\nusing base_implements = base_implements_impl&lt;D, void, I...&gt;;\r\n<\/pre>\n<p><!-- backref: C++\/WinRT implementation inheritance: Notes on winrt::implements, part 2 --> We learned from last time that this uses <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/sfinae\"> SFINAE<\/a>: to implement an &#8220;if then else&#8221; pattern. In this case, it&#8217;s saying &#8220;If <code>nested_<wbr \/>implements&lt;I...&gt;::<wbr \/>type<\/code> exists, then derive from <code>nested_<wbr \/>implements&lt;I...&gt;<\/code>. Otherwise, derive from <code>impl::<wbr \/>identity&lt;<wbr \/>root_<wbr \/>implements&lt;D, I...&gt;&gt;<\/code>.&#8221;<\/p>\n<pre>template &lt;typename T&gt;\r\nstruct identity\r\n{\r\n    using type = T;\r\n};\r\n<\/pre>\n<p>Okay, so <code>identity&lt;T&gt;::<wbr \/>type<\/code> is just <code>T<\/code>. This is basically <a title=\"What's the deal with std::type_identity?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240607-00\/?p=109865\"> a copy of <code>std::<wbr \/>type_<wbr \/>identity<\/code><\/a>. C++\/WinRT supports C++17, but <code>std::<wbr \/>type_<wbr \/>identity<\/code> didn&#8217;t show up until C++20, so C++\/WinRT provides its own copy.<\/p>\n<p>Applying this to <code>base_<wbr \/>implements_<wbr \/>impl<\/code> simplifies it to &#8220;If <code>nested_<wbr \/>implements&lt;I...&gt;::<wbr \/>type<\/code> exists, then derive from <code>nested_<wbr \/>implements&lt;I...&gt;<\/code>. Otherwise, derive from <code>root_<wbr \/>implements&lt;D, I...&gt;<\/code>.&#8221;<\/p>\n<p>So what is <code>nested_<wbr \/>implements<\/code>?<\/p>\n<pre>template &lt;typename...&gt;\r\nstruct nested_implements\r\n{};\r\n\r\ntemplate &lt;typename First, typename... Rest&gt;\r\nstruct nested_implements&lt;First, Rest...&gt;\r\n    : std::conditional_t&lt;is_implements_v&lt;First&gt;,\r\n    impl::identity&lt;First&gt;, nested_implements&lt;Rest...&gt;&gt;\r\n{\r\n    static_assert(\r\n        !is_implements_v&lt;First&gt; ||\r\n        !std::disjunction_v&lt;is_implements&lt;Rest&gt;...&gt;,\r\n        \"Duplicate nested implements found\");\r\n};\r\n<\/pre>\n<p>This is a recursively-defined <code>nested_<wbr \/>implements<\/code>. In the base case, <code>nested_<wbr \/>implements&lt;&gt;<\/code> is an empty class. Otherwise, we peel off the first template parameter and see if it derives from <code>implements<\/code>. If so, then we use it. Otherwise, we recurse on the remaining parameters.<\/p>\n<p>So <code>nested_<wbr \/>implements<\/code> searches through the template parameters and takes the first one that derives from <code>implements<\/code>. Otherwise, it&#8217;s an empty class.<\/p>\n<p>But wait, there&#8217;s extra work done in the <code>static_<wbr \/>assert<\/code>. First, let&#8217;s translate it from C++ template-ese to pseudo-code. The <code>std::disjunction<\/code> takes the logical OR of its arguments, so the second part expands to <tt>!(is_implements_v&lt;Rest1&gt; || is_implements_v&lt;Rest2&gt; || ...)<\/tt>, which says &#8220;None of the <code>Rest<\/code> is an <code>implements<\/code>.&#8221;<\/p>\n<p>Now combine this with the first part, and we get &#8220;Either <code>First<\/code> is not an <code>implements<\/code>, or none of the <code>Rest<\/code> is an <code>implements<\/code>.&#8221; If you transform this to an implication relation, you get &#8220;If <code>First<\/code> is an <code>implements<\/code>, then none of the <code>Rest<\/code> is an <code>implements<\/code>.&#8221;<\/p>\n<p>During the recursion, <code>First<\/code> progresses through all of the interface arguments, so the assertion verifies that at most one of the interface arguments supports <code>implements<\/code>.<\/p>\n<p>Okay, so unwinding back to <code>base_<wbr \/>implements<\/code>, we had previously determined that the definition was &#8220;If <code>nested_<wbr \/>implements&lt;I...&gt;::<wbr \/>type<\/code> exists, then derive from <code>nested_<wbr \/>implements&lt;I...&gt;<\/code>. Otherwise, derive from <code>impl::<wbr \/>identity&lt;<wbr \/>root_<wbr \/>implements&lt;D, I...&gt;&gt;<\/code>.&#8221; Combining this with our discovery that <code>nested_<wbr \/>implements<\/code> takes the first interface that is an <code>implements<\/code>, we see that the result is that <code>base_<wbr \/>implements<\/code> is<\/p>\n<ul>\n<li>If none of the interfaces is an <code>implements<\/code>, then use <code>root_<wbr \/>implements<\/code>.<\/li>\n<li>If exactly one of the interfaces is an <code>implements<\/code>, then use it. (It will provide the <code>root_<wbr \/>implements<\/code> so we don&#8217;t have to.)<\/li>\n<li>If more than one of the interfaces is an <code>implements<\/code>, then raise a compile-time error.<\/li>\n<\/ul>\n<p>From all this, you can figure out the legal inheritance structures for <code>winrt::<wbr \/>implements<\/code>: The <code>implements<\/code> must form a single chain of inheritance, possibly passing through other non-<code>implements<\/code> classes along the way. You cannot inherit (directly or indirectly) from multiple <code>implements<\/code>. The innermost <code>implements<\/code> provides the <code>root_<wbr \/>implements<\/code>.<\/p>\n<div id=\"p20250221_head\" style=\"display: none;\">\u00a0<\/div>\n<table style=\"border-collapse: collapse; text-align: center;\" border=\"0\" cellspacing=\"3\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\">A<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td align=\"left\"><tt>A : implements&lt;A, I1, B, I2&gt;, X1<\/tt><\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>\u2193<\/td>\n<td>\u2198<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\"><tt>implements<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\">X1<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>\u2199<\/td>\n<td>\u2193<\/td>\n<td>\u2198<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px currentcolor;\"><tt>produce&lt;A, I1&gt;<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\">B<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\"><tt>produce&lt;A, I2&gt;<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td align=\"left\"><tt>B : implements&lt;B, C, I3&gt;<\/tt><\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>\u2193<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\"><tt>implements<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>\u2193<\/td>\n<td>\u2198<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\">C<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\"><tt>produce&lt;B, I3&gt;<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td align=\"left\"><tt>C : D, X2<\/tt><\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>\u2193<\/td>\n<td>\u2198<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\">D<\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor;\">X2<\/td>\n<td>&nbsp;<\/td>\n<td align=\"left\"><tt>D : implements&lt;D, I4, I5&gt;<\/tt><\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td>\u2199<\/td>\n<td>\u2193<\/td>\n<td>\u2198<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px currentcolor;\" align=\"left\"><tt>root_<wbr \/>implements<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor; height: 0;\"><tt>produce&lt;D, I4&gt;<\/tt><\/td>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor; height: 0;\"><tt>produce&lt;D, I5&gt;<\/tt><\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Next time, we&#8217;ll look at how you can employ base classes and inheritance in your Windows Runtime implementation classes while still adhering to these restrictions.<\/p>\n<p>\n<script>\nwindow.addEventListener(\"load\", function() {\n  var fullFF = getComputedStyle(document.body).fontFamily;\n  var simpleFF = fullFF.replace(\/ Emoji\/g, \"\");\n  \/\/ break up \"style\" to prevent wordpress from injecting random junk\n  document.getElementById(\"p20250221_head\").innerHTML =\n`<s` + `tyle>\nbody { font-family: ${simpleFF}; }\n.emoji { font-family: ${fullFF}; }\n<\/s` + `tyle>`;\n});\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Discovering the legal inheritance structures for <CODE>winrt::<WBR>implements<\/CODE>.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-110895","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Discovering the legal inheritance structures for <CODE>winrt::<WBR>implements<\/CODE>.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110895","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=110895"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110895\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=110895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}