Last time, we had a straightforward function that makes an agile version of a Windows Runtime delegate. But there’s more to it.
In many cases, the delegate is already agile, so there’s no need to make an agile wrapper for something that is already agile. We can detect this case by looking for the marker interface IAgileÂObject, which all agile objects possess.
template<typename Delegate>
Delegate make_agile_delegate(Delegate const& d)
{
if (d.try_as<::IAgileObject>()) {
return d;
}
return [agile = winrt::agile_ref(d)](auto&&...args) {
return agile.get()(std::forward<decltype(args)>(args)...);
};
}
If the delegate declares itself as agile, then the delegate can be its own agile wrapper.
Wait, there another case that we missed. We’ll look at that next time.
Bonus chatter: You might think that we could try to get copy elision in the case of an agile delegate:
template<typename Delegate> Delegate make_agile_delegate(Delegate d) { if (d.try_as<::IAgileObject>()) { return d; // copy elision? } return [agile = winrt::agile_ref(d)](auto&&...args) { return agile.get()(std::forward<decltype(args)>(args)...); }; }
Unfortunately, this doesn’t work because function parameters are not eligible for copy elision.
0 comments
Be the first to start the discussion.