Task::then() should consume the original task and leave it empty
Opened this issue · 0 comments
Right now it's possible to do this:
auto task = my_coroutine();
auto subtask = task.then([]() -> QCoro::Task<> { .... });
co_await task;
co_await subtask;
This means that it's effectively possible to co_await
on task
from multiple places, making it behave somewhat like a SharedTask
, but not really (Task
is not copyable for example). Also it makes the code internally more complex.
Thus I propose to reduce the API to make .then()
available only on rvalue or xvalue Task
, so that
auto task = my_coroutine().then([]() -> QCoro::Task<> { ... });
is valid, and
auto task = my_coroutine();
auto subtask = task.then([]() -> QCoro::Task<> { ... });
is invalid.
Finally, there's this case:
auto task = my_coroutine();
auto subtask = std::move(task).then([]() -> QCoro::Task<>{ ... });
This should compile and should leave task
in a moved-from state, further we should define that co_await
ing a moved-from Task
is an error. We can choose to
- assert, or
- print a runtime warning and suspend indefinitely (since the task is not assigned to any coroutine anymore that would resume us)
I still need to think this through properly, but I think it's the right thing to do.
If people want to attach .then()
continuation to an lvalue task, they should use QCoro::SharedTask
which can be copied (once I implement it 😆 ), so that the .then()
continuation can internally capture a copy of the shared task.