cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

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

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +1, -3 Автор идеи: Игорь Шаповал

Наступает к нам С++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 абстрактный класс, только не использовать чистые виртуальные функции.

apolukhin commented 3 years ago

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

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

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

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

Andrey Davydov, 19 сентября 2018, 13:20 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 удолетворяет этому концепту, снаружи -- нет.

Игорь Шаповал, 20 сентября 2018, 9:57 Надо будет писать вроде так

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

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

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

Andrey Davydov, 15 октября 2018, 9:18 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1288r0.pdf

apolukhin commented 3 years ago

Актуальная ревици https://wg21.link/p1288