Are there any advantages of std::for_each
over for
loop? To me, std::for_each
only seems to hinder the readability of code. Why do then some coding standards recommend its use?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- How to use doMC under Windows or alternative paral
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
The nice thing with C++11 (previously called C++0x), is that this tiresome debate will be settled.
I mean, no one in their right mind, who wants to iterate over a whole collection, will still use this
Or this
when the range-based
for
loop syntax is available:This kind of syntax has been available in Java and C# for some time now, and actually there are way more
foreach
loops than classicalfor
loops in every recent Java or C# code I saw.Aside from readability and performance, one aspect commonly overlooked is consistency. There are many ways to implement a for (or while) loop over iterators, from:
to:
with many examples in between at varying levels of efficiency and bug potential.
Using for_each, however, enforces consistency by abstracting away the loop:
The only thing you have to worry about now is: do you implement the loop body as function, a functor, or a lambda using Boost or C++0x features? Personally, I'd rather worry about that than how to implement or read a random for/while loop.
You're mostly correct: most of the time,
std::for_each
is a net loss. I'd go so far as to comparefor_each
togoto
.goto
provides the most versatile flow-control possible -- you can use it to implement virtually any other control structure you can imagine. That very versatility, however, means that seeing agoto
in isolation tells you virtually nothing about what's it's intended to do in this situation. As a result, almost nobody in their right mind usesgoto
except as a last resort.Among the standard algorithms,
for_each
is much the same way -- it can be used to implement virtually anything, which means that seeingfor_each
tells you virtually nothing about what it's being used for in this situation. Unfortunately, people's attitude towardfor_each
is about where their attitude towardgoto
was in (say) 1970 or so -- a few people had caught onto the fact that it should be used only as a last resort, but many still consider it the primary algorithm, and rarely if ever use any other. The vast majority of the time, even a quick glance would reveal that one of the alternatives was drastically superior.Just for example, I'm pretty sure I've lost track of how many times I've seen people writing code to print out the contents of a collection using
for_each
. Based on posts I've seen, this may well be the single most common use offor_each
. They end up with something like:And their post is asking about what combination of
bind1st
,mem_fun
, etc. they need to make something like:work, and print out the elements of
coll
. If it really did work exactly as I've written it there, it would be mediocre, but it doesn't -- and by the time you've gotten it to work, it's difficult to find those few bits of code related to what's going on among the pieces that hold it together.Fortunately, there is a much better way. Add a normal stream inserter overload for XXX:
and use
std::copy
:That does work -- and takes virtually no work at all to figure out that it prints the contents of
coll
tostd::cout
.With C++11 and two simple templates, you can write
as a replacement for
for_each
or a loop. Why choose it boils down to brevity and safety, there's no chance of error in an expression that's not there.For me,
for_each
was always better on the same grounds when the loop body is already a functor, and I'll take any advantage I can get.You still use the three-expression
for
, but now when you see one you know there's something to understand there, it's not boilerplate. I hate boilerplate. I resent its existence. It's not real code, there's nothing to learn by reading it, it's just one more thing that needs checking. The mental effort can be measured by how easy it is to get rusty at checking it.The templates are
its very subjective, some will say that using
for_each
will make the code more readable, as it allows to treat different collections with the same conventions.for_each
itslef is implemented as a loopso its up to you to choose what is right for you.
Easy:
for_each
is useful when you already have a function to handle every array item, so you don't have to write a lambda. Certainly, thisis better than
Also, ranged
for
loop only iterates over whole containers from start to end, whilstfor_each
is more flexible.