{"id":110901,"date":"2025-02-24T07:00:00","date_gmt":"2025-02-24T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110901"},"modified":"2025-02-24T09:24:49","modified_gmt":"2025-02-24T17:24:49","slug":"20250224-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250224-00\/?p=110901","title":{"rendered":"C++\/WinRT implementation inheritance: Notes on <CODE>winrt::implements<\/CODE>, part 4"},"content":{"rendered":"<p>Last time, <a title=\"C++\/WinRT implementation inheritance: Notes on winrt::implements, part 3\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250221-00\/?p=110895\"> we figured out the rules for inheriting <code>winrt::<wbr \/>implements<\/code> in C++\/WinRT runtime class implementations<\/a>: You can use <code>winrt::<wbr \/>implements<\/code> in your class hierarchy, as long as you use single inheritance for the <code>winrt::<wbr \/>implements<\/code> part. You are not allowed to derive multiply from two different <code>winrt::<wbr \/>implements<\/code> base classes.<\/p>\n<p>One case of this is a base class that is configured at construction.<\/p>\n<pre>struct StringableInt32 :\r\n    winrt::implements&lt;StringableInt32,\r\n        winrt::Windows::Foundation::IStringable&gt;\r\n{\r\n    StringableInt32(int value) : m_value(value) {}\r\n\r\n    winrt::hstring ToString()\r\n    { return winrt::to_hstring(m_value); }\r\n\r\nprivate:\r\n    int m_value;\r\n};\r\n<\/pre>\n<p>We can use this by itself:<\/p>\n<pre>auto o = winrt::make&lt;StringableInt32&gt;(42);\r\n<\/pre>\n<p>But we can also tell the <code>implements<\/code> template that we would like to derive from it.<\/p>\n<pre>struct Derived :\r\n    winrt::implements&lt;Derived, StringableInt32&gt;\r\n{\r\n    Derived() : StringableInt32(42) {}\r\n};\r\n<\/pre>\n<p>Unfortunately, this doesn&#8217;t work because <code>StringableInt32<\/code> is an indirect base class, and you can initialize only direct base classes in the constructor. So how do you initialize the <code>StringableInt32<\/code>?<\/p>\n<p>The answer can be found by looking at the definition of <code>winrt::<wbr \/>implements<\/code>.<\/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\nprotected:\r\n\r\n    using base_type = typename\r\n        impl::base_implements&lt;D, I...&gt;::type;\r\n    using root_implements_type = typename\r\n        base_type::root_implements_type;\r\n    using is_factory = typename\r\n        root_implements_type::is_factory;\r\n\r\n    <span style=\"border: solid 1px currentcolor;\">using base_type::base_type;<\/span>\r\n<\/pre>\n<p>We saw last time that <a title=\"C++\/WinRT implementation inheritance: Notes on winrt::implements, part 3\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250221-00\/?p=110895\"> <code>base_<wbr \/>implements<\/code> looks for the template parameter that is itself derived from <code>implements<\/code><\/a>, and makes its <code>type<\/code> member type be that template parameter. We define <code>base_<wbr \/>type<\/code> to be that type, which in our case is <code>Stringable\u00adInt32<\/code>.<\/p>\n<p>The <code>using base_type::<wbr \/>base_type<\/code> imports the constructors of <code>base_type<\/code> as constructors of <code>implements<\/code>. And for us, this means that we can use the <code>StringableInt32(int value)<\/code> constructor as if it were a constructor of <code>implements<\/code>.<\/p>\n<pre>struct Derived :\r\n    winrt::implements&lt;Derived, StringableInt32&gt;\r\n{\r\n    Derived() : <span style=\"border: solid 1px currentcolor;\">implements<\/span>(42) {}\r\n};\r\n<\/pre>\n<p>The base class can expose other methods to the derived class in the usual way.<\/p>\n<pre>struct StringableInt32 :\r\n    winrt::implements&lt;StringableInt32,\r\n        winrt::Windows::Foundation::IStringable&gt;\r\n{\r\n    StringableInt32(int value) : m_value(value) {}\r\n\r\n    winrt::hstring ToString()\r\n    { return winrt::to_hstring(m_value); }\r\n\r\n    <span style=\"border: solid 1px currentcolor;\">void set_value(int value) { m_value = value; }<\/span>\r\n\r\nprivate:\r\n    int m_value;\r\n};<\/pre>\n<pre>struct Derived :\r\n    winrt::implements&lt;Derived, StringableInt32&gt;\r\n{\r\n    Derived() : implements(42) {}\r\n\r\n    <span style=\"border: solid 1px currentcolor;\">void Reset() { set_value(0); }<\/span>\r\n};\r\n<\/pre>\n<p>Okay, so this works for base classes that can fully implement an interface. But what if the base class wants to delegate part of its implementation to the derived class? We&#8217;ll look at that next time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Simple inheritance of a self-contained <CODE>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-110901","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Simple inheritance of a self-contained <CODE>implements<\/CODE>.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110901","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=110901"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110901\/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=110901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}