Skip to content

Commit 12a6bc4

Browse files
committed
Correct bad advice for use of std::for_each()
1 parent 4e043f6 commit 12a6bc4

File tree

3 files changed

+6
-11
lines changed

3 files changed

+6
-11
lines changed

10-templates-exceptions-lambdas-smart-pointers.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,22 +372,19 @@ struct MinMaxAvg {
372372
373373
int main() {
374374
vector v{ 3, 5, 2, 6, 2, 4 };
375-
MinMaxAvg f;
376-
for_each(begin(v), end(v), ref(f));
375+
MinMaxAvg f = for_each(begin(v), end(v), MinMaxAvg{});
377376
cout << "Min: " << f.min << " Max: " << f.max
378377
<< " Avg: " << f.avg << " Num: " << f.num << '\n';
379378
}
380379
```
381380

382381
A few points to note about this program:
383382

384-
* Only `num` and `first` are required to be set before the first `std::for_each()` call; we have used universal initializtion of the member variables, but this could also be achieved by using a (default-)constructor.
383+
* Only `num` and `first` are required to be set before the `std::for_each()` call; we have used universal initialization of the member variables, but this could also be achieved by using a (default-)constructor.
385384

386-
* The definition of `f` (a `MinMaxAvg` function object) is required **before** the call to `std::for_each()` so that its state is still accessible after the call. It is destroyed at the end of `main()`, as this is the scope it is declared within. The code `for_each(begin(v), end(v), MinMaxAvg{});` would compile, but its result would be lost as the functor would itself be destroyed here.
385+
* The assignment of `f` (a `MinMaxAvg` function object) is the result of the call to `std::for_each()`, being the modified (default-constructed) third parameter.
387386

388-
* The syntax `std::ref(f)` passes the function object by reference, with plain `f` a **copy** would be made which would mean the copy's member variables would be discarded at the end of the `for_each()` scope, so again the result would be lost.
389-
390-
* The function template `std::for_each()` call decomposes to the equivalent of: `f(3); f(5); f(2); f(6); f(2); f(4);`. Of course, a range-for loop could be used to accomplish the same thing, but the *logic* would have to be written (or repeated) within the body of the loop.
387+
* The function template `std::for_each()` call decomposes to the equivalent of: `auto f = MinMaxAvg{}; f(3); f(5); f(2); f(6); f(2); f(4);`. Of course, a range-for loop could be used to accomplish the same thing, but the *logic* within the functor's `operator()` would have to be written (or repeated) within the body of the loop.
391388

392389
**Experiment:**
393390

headers/10-functor2.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ struct MinMaxAvg {
2828

2929
int main() {
3030
vector v{ 3, 5, 2, 6, 2, 4 };
31-
MinMaxAvg f;
32-
for_each(begin(v), end(v), ref(f));
31+
MinMaxAvg f = for_each(begin(v), end(v), MinMaxAvg{});
3332
cout << "Min: " << f.min << " Max: " << f.max
3433
<< " Avg: " << f.avg << " Num: " << f.num << '\n';
3534
}

modules/10-functor2.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ struct MinMaxAvg {
2626

2727
int main() {
2828
vector v{ 3, 5, 2, 6, 2, 4 };
29-
MinMaxAvg f;
30-
for_each(begin(v), end(v), ref(f));
29+
MinMaxAvg f = for_each(begin(v), end(v), MinMaxAvg{});
3130
cout << "Min: " << f.min << " Max: " << f.max
3231
<< " Avg: " << f.avg << " Num: " << f.num << '\n';
3332
}

0 commit comments

Comments
 (0)