January 8th, 2024

How do I prevent my C++/WinRT implementation class from participating in COM aggregation?

In the Windows Runtime there are these things which are called “composable classes”. Composable classes allow the Windows Runtime to expose classes which applications can derive from, or at least do something that looks like class derivation, even though under the covers it’s COM aggregation.

In C++/WinRT, you can give your implementation class the winrt::composable tag to make it composable. And if you apply the unsealed keyword to your runtimeclass in the IDL file, then the C++/WinRT autogenerated implementation templates will specify winrt::composable automatically.

But what if you don’t want to be composable? How can you force a build break if somebody tries to enable composability?

From looking at the C++/WinRT code, it appears that you can detect whether the class is composable by snooping at the outer() method. For non-composing classes, outer() is defined as

static constexpr inspectable_abi* outer() noexcept { return nullptr; }

Whereas for composing classes, outer() is defined as

inspectable_abi* outer() noexcept { return m_outer; }

Therefore, we can distinguish them by seeing whether outer() is a constexpr nullptr.

struct Widget : WidgetT<Widget>
{
  Widget()
  {
    static_assert(!outer(),                         
                  "Widget must not be composable.");
  }

  ⟦ ... ⟧
};

If we are not composing, then outer() is a constexpr function that indeed returns nullptr, so everything passes.

If we are composing, then outer() is a non-constexpr function, and the static_assert fails because you are trying to assert a runtime expression at compile time.

Unfortunately, the error message doesn’t use the static assertion text, because the problem occurred even before the compiler could decide whether the expression passed the assertion.

error C2131: expression did not evaluate to a constant

But at least the line number points to the static_assert, so the developer will be taken to your assertion string.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.