Date: Sun, 26 Apr 2026 07:06:15 +0200
I don't think it's necessary to cover every possible combination of
algorithms/reductions in one function. At some point, you will just need to
use a custom loop, and that's fine.
I was refactoring code at my workplace the other day, which looked
> something like this (simplified):
>
> std::vector<int> values = ... ;
> auto isMyFavorite = [](int i) -> bool { ... };
> int* myFavorite = nullptr;
> int* minEven = nullptr;
> for (int& i : values) {
> if (!myFavorite && isMyFavorite(i))
> myFavorite = &i;
> if ((i%2==0) && (!minEven || i < *minEven)
> minEven = &i;
> }
>
It's not a great example. In your transformation below, you mention find_if,
but that's not exactly what you have here. You don't quit early when you
have found an isMyFavorite element, so you're finding the last element
matching the predicate in the range. That's not what find_if does, and it
may be a lot slower.
You can already break this up into:
- std::ranges::find_if(values, isMyFavorite)
- std::ranges::min_element(values, values | std::views::filter(even))
You're saying that you would like to do it in a single pass, but have you
actually measured whether that would improve performance meaningfully in
any scenario? That's what your idea hinges on at the end of the day. We
have a perfectly fine way to express these operations, it may just be that
a single pass is faster in some scenarios. Without that performance
benefit, I'm not seeing any motivation for the idea. It is more complicated
to cram several algorithms into one mega-function than to keep them
separated.
algorithms/reductions in one function. At some point, you will just need to
use a custom loop, and that's fine.
I was refactoring code at my workplace the other day, which looked
> something like this (simplified):
>
> std::vector<int> values = ... ;
> auto isMyFavorite = [](int i) -> bool { ... };
> int* myFavorite = nullptr;
> int* minEven = nullptr;
> for (int& i : values) {
> if (!myFavorite && isMyFavorite(i))
> myFavorite = &i;
> if ((i%2==0) && (!minEven || i < *minEven)
> minEven = &i;
> }
>
It's not a great example. In your transformation below, you mention find_if,
but that's not exactly what you have here. You don't quit early when you
have found an isMyFavorite element, so you're finding the last element
matching the predicate in the range. That's not what find_if does, and it
may be a lot slower.
You can already break this up into:
- std::ranges::find_if(values, isMyFavorite)
- std::ranges::min_element(values, values | std::views::filter(even))
You're saying that you would like to do it in a single pass, but have you
actually measured whether that would improve performance meaningfully in
any scenario? That's what your idea hinges on at the end of the day. We
have a perfectly fine way to express these operations, it may just be that
a single pass is faster in some scenarios. Without that performance
benefit, I'm not seeing any motivation for the idea. It is more complicated
to cram several algorithms into one mega-function than to keep them
separated.
Received on 2026-04-26 05:06:30
