返回 2026-07-22
⚙️ 工程

在 C++/WinRT 中创建敏捷版 Windows Runtime 委托(第二部分)Making an agile version of a Windows Runtime delegate in C++/WinRT, part 2

本文是 Raymond Chen 关于在 C++/WinRT 中创建敏捷版 Windows Runtime 委托系列文章的第二部分。重点介绍如何短路处理最简单的情况,以优化委托的敏捷性实现。

Raymond Chen

2026年7月21日

0 个反应

上次,我们写了一个简单的函数,用于创建 Windows Runtime 委托的敏捷版本。但事情并没有那么简单。

在许多情况下,委托本身已经是敏捷的,因此没有必要为已经是敏捷的对象创建敏捷包装器。我们可以通过查找标记接口 IAgile­Object 来检测这种情况,所有敏捷对象都拥有该接口。

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)...);
    };
}

如果委托声明自己是敏捷的,那么该委托就可以作为自己的敏捷包装器。

等等,我们漏掉了另一种情况。我们将在下次讨论它。

额外闲聊:你可能会认为,在敏捷委托的情况下,我们可以尝试获得复制省略:

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)...);
    };
}

遗憾的是,这行不通,因为函数参数不符合复制省略的条件。

作者

Raymond 参与了 Windows 的演进超过 30 年。2003 年,他创办了一个名为 The Old New Thing 的网站,其受欢迎程度远远超出了他最疯狂的想象,这一发展至今仍让他感到心惊肉跳。这个网站衍生出了一本书,巧合的是书名也叫 The Old New Thing(Addison Wesley 2007 年出版)。他偶尔会出现在 Windows Dev Docs 的 Twitter 账号上,讲一些毫无用处的故事。

保持关注

在发布新文章时接收通知。

关注此博客

需要完整排版与评论请前往来源站点阅读。