В C ++ 23, std :: views :: Прилегающий предоставляет скользящее окно n элементов в диапазоне. Его итератор обычно хранит n итераторы в базовом диапазоне. При реализации оператора этого итератора ++ я могу придумать два подхода:
[*]
увеличение All : текущий подход, используемый основными реализациями (LibStdc ++, MSVC). Оператор ++ просто увеличивает все n хранимых базовых итераторов.
Код: Выделить всё
// Simplified logic
for (auto & iter : current_window_iterators_) {
++iter;
}
Приращение последнего + shift : потенциально более эффективный подход. Поскольку следующее окно - это просто текущее окно, скользящее на одно, его итераторы (IT_2, IT_3, ..., IT_N, ++ IT_N) . Это может быть реализовано с помощью n-1 перемещения итератора (например, std :: shift_left ) и только one приращение базового итератора. Например, итератор для std :: views :: filter должен найти следующий элемент, который удовлетворяет предикату, который может быть дорогой. В таком трубопроводе, как источник | std :: Views :: Filter (...) | std :: views :: Прилегающий , подход «Приращение All» будет вызовать дорогостоящий приращение Filter 5 раз для каждого шага redcent_view итератор. Подход «Приращение последнего + сдвига» будет вызвать его только один раз. (Если Filter_View прикован в цепочке после Transform_view, я наблюдал, как время вызывания функции преобразования растет в геометрической прогрессии.) < /P>
По моему опыту, движения итератора почти всегда дешевы. Почему текущие стандартные реализации библиотеки используют подход «Приращение все», который кажется менее эффективным? Есть ли требование стандартного соответствия C ++, которые мне не хватает? Или это просто выбор реализации для простоты?
Подробнее здесь:
https://stackoverflow.com/questions/797 ... tors-inste