Базовые классы для корутин

Игорь Шаповал
Игорь Шаповал

Наступает к нам С++20. Я как и все надеемся, что на встрече в ноябре будут приняты в стандарт корутины.
Когда мы пишим следующее

co_await some_function();
co_await some_structure();

Мы должны научить компилятор, что с этим делать. Компилятор сам нам подказывает, какие методы мы должны реализовать.

struct some_struct {
    bool await_ready() const;
    bool await_suspend(std::coroutine_handle<> h);
    void await_resume();
}

Мне кажется на много лучше использовать абстрактный класс

struct base_awaitable {
    virtual bool await_ready() const = 0;
    virtual bool await_suspend(std::coroutine_handle<> h) = 0;
    virtual void await_resume() = 0;
};

struct some_struct : public base_awaitable {
    bool await_ready() override {};
    bool await_suspend(std::coroutine_handle<> h) override {};
    void await_resume() override {};
};

Также можно сделать к концепту Coroutine Promise абстрактный класс, только не использовать чистые виртуальные функции.

 

 

-1
рейтинг
5 комментариев
yndx-antoshkka

Виртуальные функции в столь базовой вещи не пройдут. В base_awaitable откажется указатель на таблицу виртуальных функций, в бинарнике окежется по таблице на каждого наследника и для самого базового класса + для всех них будет сгенерирован RTTI. Embedded разработчики не скажут спасибо, game dev тоже рад не будет

yndx-antoshkka
yndx-antoshkka

А вот сделать концепт Awaitable - это хорошая задумка, как раз для C++20. Можно будет проверять, что ваш класс удовлетворяет концепту

static_assert(Awaitable<my_awaitable>, "my_awaitable does not satisfy Awaitable concept");

или писать функции, принимающие только Awaitable типы данных

yndx-antoshkka
Andrey Davydov

yndx-antoshkka, концепт Awaitable он не глобальный, к примеру

struct awaiter {
    bool await_ready();
    void await_suspend(stdx::coroutine_handle<>);
    void await_resume();
};

struct awaitable {    
};

namespace test {
    awaiter operator co_await(awaitable);
}

внутри namespace test `awaitable` удолетворяет этому концепту, снаружи -- нет.

Andrey Davydov
Игорь Шаповал

Надо будет писать вроде так

template <Awaitable T>
T operator co_await() {
    return T{};
}

Или вот так если примут

auto Awaitable operator co_await() {
   return awaitable{};
}

 

 

Игорь Шаповал
Andrey Davydov

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1288r0.pdf

Andrey Davydov
Обновлено 
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения