Ограничения на реализацию 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 основан на вызове функции для каждой итерации. И вы не можете "вырваться" из функции.