【问题标题】:Non-void Coroutine Without Return Statement没有返回语句的非无效协程
【发布时间】:2017-09-13 07:35:28
【问题描述】:

我正试图围绕 C++ 协程特性展开思考。我阅读了 Kenny 的文章 (C++ - Introducing C++/WinRT) 并尝试观看此演示文稿,CppCon 2016: James McNellis “Introduction to C++ Coroutines"。我一直看到没有某种形式的 return 语句的非 void “函数”。例如,请参阅 Kenny 文章中的以下代码示例。 PrintFeedAsync 函数/协程具有 IAsyncAction 返回类型,但定义中没有返回语句。有人能解释一下这是如何工作的吗?

IAsyncAction PrintFeedAsync()
{
    Uri uri(L"http://kennykerr.ca/feed");
    SyndicationClient client;
    SyndicationFeed feed = co_await client.RetrieveFeedAsync(uri);
    for (SyndicationItem item : feed.Items())
    {
        hstring title = item.Title().Text();
        printf("%ls\n", title.c_str());
    }
}

int main()
{
    initialize();
    PrintFeedAsync().get();
}

【问题讨论】:

  • co_await 调用导致函数隐式返回 IAsyncAction

标签: visual-c++ windows-runtime c++-winrt c++-coroutine


【解决方案1】:

对于要成为协程的函数,它的返回类型必须定义一些描述协程如何工作的特征。 C++/WinRT 为其IAsyncActionIAsyncOperation<TResult> 的版本定义了这些特征。具体来说,有两种处理协程返回的方法:return_value(...)return_void()。 IAsyncOperation 使用前者,IAsyncAction 使用后者。

查看这个答案时最新的协程规范,我们发现如果协程函数的主体中没有 co_return 语句会发生什么:

如果p.return_void() 是一个有效的表达式,从协程的末尾流出就相当于一个没有操作数的co_return;否则从协程的末尾流出会导致未定义的行为。

"Programming Languages – C++ Extensions for Coroutines" (N4680) § 6.6.3.1/3

由于 C++/WinRT 定义了 return_void for IAsyncAction's traits,那么编译器将遵循上述规则。在执行从协程结束处流出的最后,使用 return_void 方法,就像您以 co_return; 结束函数一样。如果我们查看 return_void 的定义,我们会发现它相当于将状态设置为 Completed,如果有,则调用完成处理程序。

【讨论】:

    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2021-12-01
    相关资源
    最近更新 更多