C++ Logo


Advanced search

Re: async coroutines vs. lambdas

From: Avi Kivity <avi_at_[hidden]>
Date: Thu, 14 May 2020 14:34:18 +0300
On 5/14/20 2:14 PM, Ville Voutilainen wrote:
> On Thu, 14 May 2020 at 13:58, Avi Kivity via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>> Coroutines capture parameters passed by value and copy them to the
>> coroutine frame (all quotes from cppreference):
>>> When a coroutine begins execution, it performs the following:
>>> allocates the coroutine state object using operator new (see below)
>>> copies all function parameters to the coroutine state: by-value
>> parameters are moved or copied, by-reference parameters remain
>> references (and so may become dangling if the coroutine is resumed after
>> the lifetime of referred object ends)
>> This allows a coroutine's parameters to outlive the point it is launched at:
>> void foo() {
>> call_some_coroutine(a_temporary_value());
>> }
>> Normally, a_temporary_value() would e destroyed at the end of the
>> expression, which can be before the coroutine completes.
>> With a lambda coroutine, we have a problem. This is because lambdas are
>> captured by reference:
> Says what?

Says the quote below, from cppreference.

>>> If the coroutine is a non-static member function, such as task<void>
>> my_class::method1(int x) const;, its Promise type is
>> std::coroutine_traits<task<void>, const my_class&, int>::promise_type

[] (int) -> task<void> is equivalent to my_class::operator()(int) const
-> task<void>.

>> For a lambda, the non-static member function is
>> synthetic_lambda_type::operator() const, and so the lambda would be
>> captured as const synthetic_lambda_type&. Consider this call:
> No. The lambda is the coroutine, not its operator().

The first five words from cppreference are "A coroutine is a function".
I know it is not authoritative, but I've seen nothing to contradict it.

Received on 2020-05-14 06:37:23