{"id":106569,"date":"2022-05-04T07:00:00","date_gmt":"2022-05-04T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106569"},"modified":"2022-05-04T06:49:43","modified_gmt":"2022-05-04T13:49:43","slug":"20220504-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20220504-00\/?p=106569","title":{"rendered":"Producing an empty Windows Runtime type in C++\/WinRT"},"content":{"rendered":"<p>Windows Runtime types fall into two general categories: Reference types and value types.<\/p>\n<p>Reference types are copied by reference. When you copy a reference type, you&#8217;re really just incrementing the reference count on the underlying object. And Windows Runtime references can be null.<\/p>\n<p>Value types are copied by value. When you copy a value type, you are making a shallow copy of everything inside it. Windows Runtime values cannot be null.<\/p>\n<p>There are cases where you want to produce an empty Windows Runtime type. For reference types, this would be a null reference, and for value types, it would be a default-initialized value filled with zero, <code>false<\/code>, and null, as appropriate.<\/p>\n<p>In other words, we want to replicate what C# <code>default(T)<\/code> does.<\/p>\n<p>Using <code>{}<\/code> to generate an empty value works for delegates, interfaces, and value types, but not for runtime classes, because C++\/WinRT expresses the default constructor of the runtime class as the default constructor of the projection. In other words, default-constructing a Windows Runtime class in C++\/WinRT actually <i>creates an object<\/i>, so you don&#8217;t get <code>nullptr<\/code> at all. You get a real live object.<\/p>\n<p>We need to detect the case where we have a Windows Runtime runtime class and use the <code>nullptr<\/code> constructor in that case.<\/p>\n<p>The shortcut here is that the <code>nullptr<\/code> constructor also works for delegates and interfaces, we can just use it for all reference types.<\/p>\n<p>And that leads us to this:<\/p>\n<pre>template&lt;typename T&gt;\r\nconstexpr T winrt_empty_value() noexcept\r\n{\r\n    if constexpr (std::is_base_of_v&lt;winrt::Windows::Foundation::IUnknown, T&gt;) {\r\n        return nullptr;\r\n    } else {\r\n        return {};\r\n    }\r\n}\r\n<\/pre>\n<p>Making the whole thing <code>constexpr<\/code> allows it to be used a lot of places that would normally be constrained to constants.<\/p>\n<p>This function will come in handy later, but we&#8217;ll have to get there first.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to say that you don&#8217;t have anything.<\/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-106569","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>How to say that you don&#8217;t have anything.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106569","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=106569"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106569\/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=106569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}