Как стать автором
Обновить

Комментарии 11

Потому, что эффективно реализовать yield в компилируемом языке программирования не так просто. Иначе бы yield давно уже был в C++. Особенно непросто учесть случаи вызова yield в рекурсивных функциях (а это может использоваться например при рекурсивном обходе директорий).

Ну так-то co_yield уже года 4 есть в C++, а в C++23 добавили к нему некоторую библиотечную обвязку, например, std::generator, который превращает корутину с этим co_yield в нечто итерируемое. Правда, @Kelbon скажет (и покажет), что генератор можно было бы сделать и получше, но это детали. Если не нравится стандартный генератор, то можно написать свой, для этого в языке все есть.

в дереве где всего одно значение это не так впечатляюще выглядит, но с директориями это классический сценарий для рекурсивного генератора

// псевдокод не обрабатывающий много чего
generator<file_entry> directory_recursive(filesystem::path p) {
  for (auto&& entry : entriees_of(p)) {
    if (entry.is_direectory())
      co_yield elements_of(directory_recursive(entry.path));
    else
      co_yild entry;
  }
}

Да, появление std:generator в C++ я как-то пропустил.

Но судя по страничке Compiler support for C++23 std::generator на данный момент поддерживается только одним компилятором: GCC 14-й версии, который вышел совсем недавно — 07.05.2024.

И скорее всего, реализована эта штука очень неоптимально.
Я написал простейший генератор, который производит целые числа из заданного диапазона:

std::generator<int> range_generator(int start, int stop)
{
    for (int i = start; i < stop; i++)
        co_yield i;
}

Не берусь судить об эффективности сгенерированного компилятором кода, но выглядит страшно.

Вообще, co_yield — это же про асинхронный код. И будет ли co_yield когда-нибудь оптимизирован C++-компиляторами для синхронных генераторов — большой вопрос.

Хорошая классификация итераторов, спасибо.

Наверное после разбора разных схем и отличий вашей схемы от с# и D можно расширить табличку из слайда ещё одной колонкой, start. Start у всех будет совпадать с done? кроме 11l. Концептуально табличка хороша.

С++ итераторы у вас реализованы некорректно- begin() и end() должны возвращать одинаковый тип, ни один стандартный алгоритм из <algorithm> не будет работать с вашими итераторами.

И это кстати общий случай который 11l ломает- для итераторов в таком стиле каждый алгоритм требует быть определённым для пустого begin() - не удобно, раздуваем итератор (т.к optional теперь деталь реализации итератора)

Касательно реализации итератора по строкам - во первых странно строить новые типы итераторов на базе iostream который сам итератор и понятно что получается сложно местами. has_next можно убрать если проверять поток на окончание.

Из C# итератора вы выкинули главное его свойство - ленивость(создание итератора не запускает чтение данных)

С итерацией по директориям вы тоже перемудрили.

Ну и итераторы это то где как раз уместно оптимизировать производительность вплоть до инструкций.

В общем тема интересная, но над содержанием и выводами надо критически поработать.

Это скорее для ренджей из C++20, ну и в range-based for тоже будет работать из-за его семантики, но не в "классических" алгоритмах, например std::for_each с этим сентинелом работать не сможет.

var it = collection.__iter__();
while (true) {
    try {
        let current = it.__next__();
        ...current...
    }
    catch (StopIteration) {
        break;
    }
}

Для начала отступы а не скобки. Далее что за var и let, это не жс. Это не питон короче

А так если нет элементов none

while (current := next(it, None)) is not None:
    ...

Это не питон короче

Это псевдокод.
Или как вы предлагаете следовало поступить?
Код обхода итератора всегда писать на том языке программирования, к которому он относится?

Не все знакомы с синтаксисом Python или того же Rust.

Поэтому я выбрал что-то среднее между C++/C# и JavaScript, т.к. синтаксис Си-подобных языков знаком большинству программистов.

Добавил в статью "код обхода итератора на том языке программирования, к которому он относится" в спойлере.

Ещё забыли модель итераторов Lua.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории