I am trying to wrap my head around the C++ coroutine feature. I read Kenny's article (C++ - Introducing C++/WinRT) and also tried watching this presentation, CppCon 2016: James McNellis “Introduction to C++ Coroutines". I keep seeing non-void "functions" without some form of return statement. As an example, see the following code sample from Kenny's article. The PrintFeedAsync function/coroutine has an IAsyncAction return type but there is no return statement in the definition. could someone explain how this works?
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();
}
For a function to be a coroutine, its return type has to have certain traits defined that describes how the coroutine will work. C++/WinRT defines those traits for their version of
IAsyncAction
orIAsyncOperation<TResult>
. Specifically, there are two methods that handle returning from a coroutine:return_value(...)
orreturn_void()
. IAsyncOperation uses the former, and IAsyncAction uses the latter.Looking at the latest coroutine spec at the time of this answer, we find what happens if there is no co_return statement in the body of a coroutine function:
Since C++/WinRT defines a return_void for IAsyncAction's traits then the compiler will follow the above rule. At the end where execution flows off the end of the coroutine, the return_void method is used, the same as if you ended the function with
co_return;
. If we look at the definition of return_void, we see it's equivalent to setting the status as Completed and calling the completion handler if there is one.