Date: Sat, 25 Apr 2026 23:18:10 +0200
Hi,
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;
}
and I realized there seems to be no elegant way to achieve this with a STL
one-liner.
Many things I can achieve with the amazing <ranges> and <algorithm>
libraries and they simplify the production code quite a bit, but not this
one.
The 'missing' facility is this: with only a single-pass of the input range,
perform multiple reductions* in parallel**.
*: By "reduction" I mean calculations similar to <algorithm>'s find_if,
any_of/all_of/..., min/max, possibly complicated with
transformations/filters.
**: Not "multithreaded parallel", just "at the same time".
ChatGPT mentioned Clojure transducers as an example of what I am looking
for. I am not familiar with Clojure. Took a look. It does sound like the
thing I am looking for, just in C++.
How this might look in C++ (namespace 'red' stands for some new imagined
namespace):
auto even = [](int i) -> bool { ... };
auto [myFavorite, minEven] = std::ranges::multi_reduce(values,
red::find_if(isMyFavorite), red::filter(even) | red::min);
// myFavorite could be an iterator
// minEven could be std::optional<int>
This is all just a quick sketch, without any implementation details, etc...
Reminiscent of ranges and range algorithms, but there is a fundamental
mathematical difference here, and I believe that ranges are not a solution
to this problem at all (not even as building blocks or primitives).
I can imagine a rich family of such reduction primitives that are
composable and extendable (customization point objects, like comparators
and projections in range algorithms, but also user-defined classes with
special capabilities, std::ranges::view_interface or iterator traits come
to mind).
My question is, is there already some proposal addressing this, or should I
pursue this idea?
Thank You for reading this!
Matthew
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;
}
and I realized there seems to be no elegant way to achieve this with a STL
one-liner.
Many things I can achieve with the amazing <ranges> and <algorithm>
libraries and they simplify the production code quite a bit, but not this
one.
The 'missing' facility is this: with only a single-pass of the input range,
perform multiple reductions* in parallel**.
*: By "reduction" I mean calculations similar to <algorithm>'s find_if,
any_of/all_of/..., min/max, possibly complicated with
transformations/filters.
**: Not "multithreaded parallel", just "at the same time".
ChatGPT mentioned Clojure transducers as an example of what I am looking
for. I am not familiar with Clojure. Took a look. It does sound like the
thing I am looking for, just in C++.
How this might look in C++ (namespace 'red' stands for some new imagined
namespace):
auto even = [](int i) -> bool { ... };
auto [myFavorite, minEven] = std::ranges::multi_reduce(values,
red::find_if(isMyFavorite), red::filter(even) | red::min);
// myFavorite could be an iterator
// minEven could be std::optional<int>
This is all just a quick sketch, without any implementation details, etc...
Reminiscent of ranges and range algorithms, but there is a fundamental
mathematical difference here, and I believe that ranges are not a solution
to this problem at all (not even as building blocks or primitives).
I can imagine a rich family of such reduction primitives that are
composable and extendable (customization point objects, like comparators
and projections in range algorithms, but also user-defined classes with
special capabilities, std::ranges::view_interface or iterator traits come
to mind).
My question is, is there already some proposal addressing this, or should I
pursue this idea?
Thank You for reading this!
Matthew
Received on 2026-04-25 21:18:24
