Когда использовать сопрограммы над итераторами? - PullRequest
0 голосов
/ 20 января 2019

Допустим, у меня есть данные, которые я хочу предоставить «по одному». Там много данных, поэтому я получаю один кусок только тогда, когда он нужен (для экономии памяти). Поэтому я не могу хранить все данные внутри std::vector.

Сегодня я могу использовать для этого итераторы, поскольку они естественным образом соответствуют этому требованию. Но я также мог бы использовать сопрограммы (в настоящее время использую Coroutines TS). Использование алгоритмов, использующих только итераторы, не требуется.

Есть ли в этом случае преимущество использования сопрограмм по сравнению с итераторами?

1 Ответ

0 голосов
/ 20 января 2019

Итераторы действуют как своего рода клей, позволяющий пользователям писать алгоритмы, которые работают с последовательностями значений, не зная о том, как эта последовательность появилась или удерживается. Но конкретный «клей» между алгоритмом и последовательностью не имеет значения. Имеет значение только то, что конкретная реализация алгоритма должна быть реализована в терминах определенного вида «клея».

Стандартная модель итератора библиотеки полезна, потому что стандартная библиотека поставляется с инструментами, которые используют эту модель (алгоритмы, конструкторы итераторов контейнеров, основанные на диапазоне for и т. Д.). Если вы на самом деле не используете эти механизмы ... тогда нет ничего объективного в использовании модели итератора по сравнению с любой другой моделью. Вы можете просто иметь объект, который имеет функцию get_next и has_next, или какой-то подобный интерфейс. Все они примерно одинаково эффективны, и их нетрудно преобразовать из одного в другое.

Сопрограммы были бы полезны в этом отношении только в той степени, в которой это упрощает реализацию операции. Код, использующий сопрограмму генерации, будет иметь в основном тот же интерфейс, что и раньше; он просто внутренне использует co_yield и кадр стека, который делает паузу и возобновляет.

Поскольку стековый фрейм сопрограммы - это объект, который сохраняется, вам не нужно явно создавать объект генерации. Функция, которая генерирует значения, может использовать переменные стека для своего состояния, а затем co_yield значения из этих данных стека по мере необходимости. Это позволило бы вам создать обобщенную структуру генератора, которую могли бы использовать многие различные функции, создав таким образом некоторое разделение между общим интерфейсом для всех генераторов и конкретным кодом, выполняющим генерацию.

...