Итераторы действуют как своего рода клей, позволяющий пользователям писать алгоритмы, которые работают с последовательностями значений, не зная о том, как эта последовательность появилась или удерживается. Но конкретный «клей» между алгоритмом и последовательностью не имеет значения. Имеет значение только то, что конкретная реализация алгоритма должна быть реализована в терминах определенного вида «клея».
Стандартная модель итератора библиотеки полезна, потому что стандартная библиотека поставляется с инструментами, которые используют эту модель (алгоритмы, конструкторы итераторов контейнеров, основанные на диапазоне for
и т. Д.). Если вы на самом деле не используете эти механизмы ... тогда нет ничего объективного в использовании модели итератора по сравнению с любой другой моделью. Вы можете просто иметь объект, который имеет функцию get_next
и has_next
, или какой-то подобный интерфейс. Все они примерно одинаково эффективны, и их нетрудно преобразовать из одного в другое.
Сопрограммы были бы полезны в этом отношении только в той степени, в которой это упрощает реализацию операции. Код, использующий сопрограмму генерации, будет иметь в основном тот же интерфейс, что и раньше; он просто внутренне использует co_yield
и кадр стека, который делает паузу и возобновляет.
Поскольку стековый фрейм сопрограммы - это объект, который сохраняется, вам не нужно явно создавать объект генерации. Функция, которая генерирует значения, может использовать переменные стека для своего состояния, а затем co_yield
значения из этих данных стека по мере необходимости. Это позволило бы вам создать обобщенную структуру генератора, которую могли бы использовать многие различные функции, создав таким образом некоторое разделение между общим интерфейсом для всех генераторов и конкретным кодом, выполняющим генерацию.