Ограничения на реализацию std:: for_each
В § 25.2.4.2 стандарта С++ (std::for_each
):
template<class InputIterator, class Function> Function
for_each(InputIterator first, InputIterator last, Function f);
Эффекты: Применяет f к результату разыменования каждого итератора в диапазон [первый, последний], , начиная с первого и продолжающийся до последнего - 1.
- Означает ли это, что f применяется к элементам контейнера в порядке?
- Если да, нарушает ли его параллельный режим libstdС++?
- Если нет, то почему цикл, основанный на диапазоне, в п. 6.5.5 не реализован как вызов std:: for_each? (это позволяло бы автоматическое распараллеливание циклов на основе диапазонов путем реализации)
Ответы
Ответ 1
- Означает ли это, что
f
применяется к элементам контейнера в порядке?
Я изначально сказал "нет", но я думаю, что это значит, что да. Другие алгоритмы не включают эту конкретную формулировку.
- Если да, нарушает ли параллельный режим libstdС++?
Возможно, параллельный режим является расширением и несколько экспериментальным, не претендующим на 100% -ую реализацию стандартной библиотеки. (Если он утверждает, что где-то в документах я исправлю документы!; -)
- Если нет, то почему цикл, основанный на диапазоне, в п. 6.5.5 не реализован как вызов std:: for_each? (это позволит автоматически разбить циклы на основе диапазона).
Диапазон for
не зависит от стандартной библиотеки для работы. Если видны std::begin
и std::end
, они могут использоваться, но не требуются. Кроме того, это будет связано с упаковкой тела цикла в виде лямбда, поэтому у вас есть объект функции, который пройдет до std::for_each
, что усложнит спецификацию for
на основе диапазона, которая должна иметь одинаковую семантику и быть точно такой же эффективный, как рукописный цикл for
. Но реальная причина может заключаться в том, что никто не думал так поступать!
Ответ 2
Если нет, то почему цикл, основанный на диапазоне, в п. 6.5.5 не реализован как вызов std:: for_each? (это позволит автоматически разбивать циклы на основе диапазонов)
Ну, std::for_each
не допускается, чтобы стандарт был "автоматически распараллелен" (он должен выполняться последовательно, как указано в стандарте), так что это. Но что более важно, диапазон for
на основе диапазона позволяет другим вещам помимо std::for_each
. В качестве языковой функции вы выходите, например, из break
из цикла. Вы можете использовать goto
или другие языковые конструкции. И так далее.
std::for_each
основан на вызове функции для каждой итерации. И вы не можете "вырваться" из функции.