I've been using ranges for a while, and each time I use filtering I feel like it can be easily replaced with a plain old if and continue statement. Consider these snippets of code:
for (auto value : values | ranges::views::filtered([](auto value) { /* ... */ })) {
// ... do something with value
}
for (auto value : values) {
if (/* ... */) continue;
// ... do something with value
}
To me the second option looks way more readable. Besides, the first option may potentially involve some additional call overhead. So what are the advantages of filtering? Are there some guidelines on when I should choose one or another?
Second version (
continue) is much easier to read, compatible with older c++ standards, and very close to the actual execution behind. First version will most likely be optimized to a very close binary code, but its syntax is in my opinion, overly complex and involves a lot of compile time optimizations of the template classes behind.First version has zero advantages. Your thought is good, with recent c++ features people tend to overthink and bloat iterations.
EDIT : Comments pointed that I'm wrong about the temporary filtered list allocation. So both codes might produce the same exact instructions at the end. However, the arguments that second version is much simpler and readable as well as compatible with older c++ standards without drawbacks, still stand.
You also have a slightly different version:
I tend to prefer that one, because the control flow is more visually obvious than a
continue. But that's a fully personal taste matter.