Hello again! In this video, we are going to look at the for_each() algorithm. for underscore each takes
an iterator range and a callable object. It will iterate over the range and call this function with
each element as the argument.
So here we have the begin() and end() for the string.
We have a lambda expression which points out the elements, followed by a semicolon.
And we could write this using a range-for loop.
So we just iterate over all the characters and print each one out.
So here is that code, we have our string here.
We call for_each() with begin() and end() as the arguments and the lambda expression, which will print
out each character.
And then we have the range for loop.
So there we are.
We get the characters in the string displayed on screen, with a comma between each one.
The function can also take the element by reference, which means we can change the element. So we
have the begin() and end() databases, and we have a lambda expression which takes the element by reference
and replace it with the uppercase equivalent.
And again, we could write this as a range for loop, with reference to auto as the type of the element.
And then we have our for_each() call, the lambda expression and the range-for.
And both those will convert the characters to uppercase.
So you may be wondering what the point is of having this for_each() algorithm if you can use a range-for
a loop instead.
And the main reason is historic. Range-for loops only came in in C++11.
But the algorithms came in in C++ 98.
So for those 13 years, if you wanted to call a function with each element in the container as argument,
then for_each() was the best way to do it.
Now we have range-for loops, and usually these are the better choice.
The code is shorter and clearer, and also you can put in break or return statements if you want to
terminate the loop early.
On the other hand, there are some situations where for_each() is still useful. If you only want a sub-range
so part of a container and not the whole container. There is a single path through the code.
There are no branches, and no early returns.
So that makes it easier to optimize.
And if there are some loop-related things which your implementation does not yet support, it is a useful
fallback.
Visual C++ took a long time to add support for range-for loops.
So until 2015, Microsoft's advice was to use for_each().
In C++17, many algorithms are being converted to work with parallel processing, but obviously it
takes time for compiler implementers to write all that code.
However, there is a parallel version of for_each.
So if you want an algorithm which is not yet available in parallel form, but you can convert it to
use for_each(), then that is a way of getting a parallel version of that algorithm, for the time being.
OK, so that is it for this video.
I will see you next time.
Until then, keep coding!