{"id":102577,"date":"2019-06-10T07:00:00","date_gmt":"2019-06-10T14:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102577"},"modified":"2019-06-09T15:20:31","modified_gmt":"2019-06-09T22:20:31","slug":"how-can-i-determine-in-a-c-header-file-whether-c-cx-is-enabled-how-about-c-winrt","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190610-00\/?p=102577","title":{"rendered":"How can I determine in a C++ header file whether C++\/CX is enabled? How about C++\/WinRT?"},"content":{"rendered":"<p>Suppose you&#8217;re writing a header file that wants to take advantage of C++\/CX or C++\/WinRT features if the corresponding functionality is available.<\/p>\n<pre>\/\/ async_event_helpers.h\r\n\r\n#if (? what goes here ?)\r\n\r\n\/\/ RAII type to ensure that a C++\/CX deferral is completed.\r\n\r\ntemplate&lt;typename T&gt;\r\nstruct ensure_complete\r\n{\r\n   ensure_complete(T^ deferral) : m_deferral(deferral) { }\r\n   ~ensure_complete() { if (m_deferral) m_deferral-&gt;Complete(); }\r\n\r\n  ensure_complete(ensure_complete const&amp;) = delete;\r\n  ensure_complete&amp; operator=(ensure_complete const&amp;) = delete;\r\n\r\n  ensure_complete(ensure_complete&amp;&amp; other)\r\n  : m_deferral(std::exchange(other.m_deferral, {})) { }\r\n  ensure_complete&amp; operator=(ensure_complete&amp;&amp; other)\r\n  { m_deferral = std::exchange(other.m_deferral, {}); return *this; }\r\n\r\nprivate:\r\n   T^ m_deferral;\r\n};\r\n#endif\r\n\r\n#if (? what goes here?)\r\n\r\n\/\/ RAII type to ensure that a C++\/WinRT deferral is completed.\r\n\r\ntemplate&lt;typename T&gt;\r\nstruct ensure_complete\r\n{\r\n   ensure_complete(T const&amp; deferral) : m_deferral(deferral) { }\r\n   ~ensure_complete() { if (m_deferral) m_deferral.Complete(); }\r\n\r\n  ensure_complete(ensure_complete const&amp;) = delete;\r\n  ensure_complete&amp; operator=(ensure_complete const&amp;) = delete;\r\n\r\n  ensure_complete(ensure_complete&amp;&amp;) = default;\r\n  ensure_complete&amp; operator=(ensure_complete&amp;&amp;) = default;\r\n\r\nprivate:\r\n   T m_deferral{ nullptr };\r\n};\r\n#endif\r\n<\/pre>\n<p>What magic goes into the <code>#if<\/code> statement to enable the corresponding helpers only if the prerequisites have been met?<\/p>\n<p>For C++\/CX, the magic incantation is<\/p>\n<pre>#ifdef __cplusplus_winrt\r\n<\/pre>\n<p>If C++\/CX is enabled, then the <code>__cplusplus_winrt<\/code> symbol <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/preprocessor\/predefined-macros?view=vs-2017\"> is defined as the integer 201009<\/a>, which is presumably a version number.<\/p>\n<p>For C++\/WinRT, the magic symbol is<\/p>\n<pre>#ifdef CPPWINRT_VERSION\r\n<\/pre>\n<p>This is defined to a string literal representing the version of C++\/WinRT that is active. In addition to serving as a feature detector, this macro is used to ensure that all of the C++\/WinRT header files you use are compatible with each other. (If not, you will get a compile-time assertion failure.)<\/p>\n<p>The C++\/WinRT team cautions that this is the <i>only<\/i> macro in the C++\/WinRT header file that is supported for feature detection. Do not rely on the other <code>WINRT_*<\/code> macros in the C++\/WinRT header files. They are implementation details and may change at any time.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For conditionally enabling features, say.<\/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-102577","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>For conditionally enabling features, say.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102577","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=102577"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102577\/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=102577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}