WEBVTT

00:00.150 --> 00:06.780
Hello again! In this video, we are going to look at the for_each() algorithm. for underscore each takes

00:06.780 --> 00:13.860
an iterator range and a callable object. It will iterate over the range and call this function with

00:13.860 --> 00:15.390
each element as the argument.

00:16.650 --> 00:19.290
So here we have the begin() and end() for the string.

00:19.620 --> 00:24.210
We have a lambda expression which points out the elements, followed by a semicolon.

00:25.530 --> 00:28.200
And we could write this using a range-for loop.

00:28.620 --> 00:31.620
So we just iterate over all the characters and print each one out.

00:34.170 --> 00:36.420
So here is that code, we have our string here.

00:37.950 --> 00:42.900
We call for_each() with begin() and end() as the arguments and the lambda expression, which will print

00:42.900 --> 00:43.710
out each character.

00:44.550 --> 00:46.020
And then we have the range for loop.

00:48.690 --> 00:49.410
So there we are.

00:49.560 --> 00:53.940
We get the characters in the string displayed on screen, with a comma between each one.

00:56.180 --> 01:02.000
The function can also take the element by reference, which means we can change the element. So we

01:02.000 --> 01:07.910
have the begin() and end() databases, and we have a lambda expression which takes the element by reference

01:08.630 --> 01:10.910
and replace it with the uppercase equivalent.

01:11.780 --> 01:17.870
And again, we could write this as a range for loop, with reference to auto as the type of the element.

01:22.260 --> 01:27.840
And then we have our for_each() call, the lambda expression and the range-for.

01:30.540 --> 01:33.240
And both those will convert the characters to uppercase.

01:35.130 --> 01:40.240
So you may be wondering what the point is of having this for_each() algorithm if you can use a range-for

01:40.240 --> 01:40.890
a loop instead.

01:41.490 --> 01:46.350
And the main reason is historic. Range-for loops only came in in C++11.

01:46.740 --> 01:49.890
But the algorithms came in in C++ 98.

01:50.490 --> 01:56.250
So for those 13 years, if you wanted to call a function with each element in the container as argument,

01:56.580 --> 01:58.380
then for_each() was the best way to do it.

01:59.610 --> 02:02.520
Now we have range-for loops, and usually these are the better choice.

02:02.820 --> 02:08.790
The code is shorter and clearer, and also you can put in break or return statements if you want to

02:08.790 --> 02:09.870
terminate the loop early.

02:11.730 --> 02:17.430
On the other hand, there are some situations where for_each() is still useful. If you only want a sub-range

02:17.610 --> 02:23.200
so part of a container and not the whole container. There is a single path through the code.

02:23.220 --> 02:25.620
There are no branches, and no early returns.

02:26.010 --> 02:27.810
So that makes it easier to optimize.

02:29.610 --> 02:35.100
And if there are some loop-related things which your implementation does not yet support, it is a useful

02:35.100 --> 02:35.610
fallback.

02:35.910 --> 02:39.870
Visual C++ took a long time to add support for range-for loops.

02:40.500 --> 02:44.610
So until 2015, Microsoft's advice was to use for_each().

02:46.380 --> 02:52.170
In C++17, many algorithms are being converted to work with parallel processing, but obviously it

02:52.170 --> 02:56.280
takes time for compiler implementers to write all that code.

02:56.700 --> 02:59.070
However, there is a parallel version of for_each.

02:59.640 --> 03:05.070
So if you want an algorithm which is not yet available in parallel form, but you can convert it to

03:05.070 --> 03:10.680
use for_each(), then that is a way of getting a parallel version of that algorithm, for the time being.

03:12.130 --> 03:14.100
OK, so that is it for this video.

03:14.550 --> 03:15.390
I will see you next time.

03:15.630 --> 03:17.700
Until then, keep coding!
