{"id":104218,"date":"2020-09-14T07:00:00","date_gmt":"2020-09-14T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104218"},"modified":"2020-09-14T07:06:46","modified_gmt":"2020-09-14T14:06:46","slug":"20200914-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200914-00\/?p=104218","title":{"rendered":"What&#8217;s up with error C4838: a WinRT type cannot be a member of a union, and how can I work around it?"},"content":{"rendered":"<p>If you try to put a Windows Runtime type inside a <code>std::optional<\/code> from C++\/CX, you get this error:<\/p>\n<pre style=\"white-space: pre-wrap;\">std::optional&lt;::Windows::Foundation::Rect&gt; optRect;\r\n\r\nerror C2848: 'std::_Optional_destruct_base&lt;_Ty,true&gt;::Value': A WinRT type cannot be a member of a union\r\n<\/pre>\n<p>Why can&#8217;t a WinRT type be a member of a union?<\/p>\n<p>The C++\/CX language extension was written back when the latest C++ standard was C++03, and in C++03, unions could not (among other things) contain objects that had a nontrivial destructor.<\/p>\n<p>Windows Runtime types usually have destructors: Reference types use hat pointers which release the underlying ABI object at destruction. And structures might contain <code>String^<\/code>, which also entails a nontrivial destructor.<\/p>\n<p>C++\/CX just gives up and says, &#8220;Nope, not gonna do that.&#8221; It doesn&#8217;t bother to check whether the structure in question actually has a nontrivial destructor; it just assumes that it does, and the compiler won&#8217;t let you put it into a union. C++\/CX won&#8217;t even let you put a Windows Runtime enum in a union!<\/p>\n<p>Fortunately, C++\/WinRT doesn&#8217;t have this problem. C++\/WinRT is standard C++, and the compiler can see that the <code>Rect<\/code> structure is just a bunch of <code>float<\/code>s with no special destructor. Furthermore, C++\/WinRT can take advantage of advances in the C++ language, such as permitting objects with destructors in unions.<\/p>\n<pre>\/\/ compiles just fine\r\nstd::optional&lt;winrt::Windows::Foundation::Rect&gt; optRect;\r\n<\/pre>\n<p>Just one of many reasons why C++\/CX is deprecated in favor of C++\/WinRT.<\/p>\n<p><b>Bonus chatter<\/b>: If you really need to put a C++\/CX <code>Rect<\/code> into a union, you can wrap it inside another structure first.<\/p>\n<pre>struct RectStruct\r\n{\r\n  ::Windows::Foundation::Rect rect;\r\n};\r\n\r\nstd::optional&lt;RectStruct&gt; optRect;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A restriction left over from C++03.<\/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-104218","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A restriction left over from C++03.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104218","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=104218"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104218\/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=104218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}