Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrictions on std::for_each implementation

Tags:

c++

foreach

c++11

In §25.2.4.2 of the C++ standard (std::for_each):

template<class InputIterator, class Function>   Function
for_each(InputIterator first, InputIterator last, Function f);

Effects: Applies f to the result of dereferencing every iterator in the range [first,last), starting from first and proceeding to last - 1.

  • Does this mean that f is applied to the elements of a container in order?
  • If so, does the parallel mode of libstdc++ violate it?
  • If not, why is the range-based for loop in §6.5.4 not implemented as a call to std::for_each? (this would allow range-based for loops to also be automatically parallelized by the implementation)
like image 936
gnzlbg Avatar asked Feb 12 '13 17:02

gnzlbg


2 Answers

  • Does this mean that f is applied to the elements of a container in order?

I originally said no, but I think it does mean that, yes. Other algorithms don't include that specific wording.

  • If so, does the parallel mode of libstdc++ violate it?

Maybe, the parallel mode is an extension, and somewhat experimental, not really claiming to be a 100% conforming implementation of the standard library. (If it does claim that somewhere in the docs I'll fix the docs! ;-)

  • If not, why is the range-based for loop in §6.5.4 not implemented as a call to std::for_each? (this would allow range-based for loops to also be automatically parallelized)

Range-based for does not depend on the standard library to work. If std::begin and std::end are visible they might be used, but are not required. Also, it would involve packaging up the loop body as a lambda so you have a function object to pass to std::for_each, which would complicate the specification of range-based for, which is supposed to have the same semantics and be exactly as efficient as a hand-written for loop. But the real reason might be that noone thought to do it that way!

like image 148
Jonathan Wakely Avatar answered Oct 03 '22 15:10

Jonathan Wakely


If not, why is the range-based for loop in §6.5.4 not implemented as a call to std::for_each? (this would allow range-based for loops to also be automatically parallelized)

Well, std::for_each is not allowed by the standard to be "automatically parallelized" (it must proceed sequentially, as stated in the standard), so there's that. But more importantly, range-based for allows other things besides std::for_each. As a language feature, you get to, for example, break out of the loop. You can use goto or other language constructs. And so forth.

std::for_each is based around calling a function for each iteration. And you can't really "break" out of a function.

like image 32
Nicol Bolas Avatar answered Oct 03 '22 14:10

Nicol Bolas