Не пустые сопрограммы без возврата

Я пытаюсь обернуть голову вокруг функции сопрограммы C++. Я прочитал статью Кенни ( C++ - Представляем C++ / WinRT), а также попытался посмотреть эту презентацию, CppCon 2016: Джеймс МакНеллис "Введение в сопрограммы C++". Я продолжаю видеть "пустые" "функции" без какой-либо формы выражения return. В качестве примера см. следующий пример кода из статьи Кенни: Функция / сопрограмма 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();
}

1 ответ

Чтобы функция была сопрограммой, в ее типе возврата должны быть определены определенные черты, описывающие, как будет работать сопрограмма. C++/WinRT определяет эти черты для их версии IAsyncAction или же IAsyncOperation<TResult>, В частности, есть два метода, которые обрабатывают возврат из сопрограммы: return_value(...) или же return_void(), IAsyncOperation использует первое, а IAsyncAction использует второе.

Глядя на последнюю спецификацию сопрограммы на момент этого ответа, мы находим, что происходит, если в теле функции сопрограммы нет оператора co_return:

Если p.return_void() допустимое выражение, вытекающее из конца сопрограммы эквивалентно co_return без операнда; в противном случае утечка из конца сопрограммы приводит к неопределенному поведению.

- "Языки программирования - расширения C++ для сопрограмм" (N4680) § 6.6.3.1/3

Так как C++ / WinRT определяет return_void для признаков IAsyncAction, компилятор будет следовать вышеупомянутому правилу. В конце, где выполнение вытекает из конца сопрограммы, используется метод return_void, так же, как если бы вы завершили функцию с помощью co_return;, Если мы посмотрим на определение return_void, то увидим, что это эквивалентно установке статуса "Завершено" и вызову обработчика завершения, если он есть.

Другие вопросы по тегам