In C 23, the ranges (sub)library has gained std::ranges::zip
, which zips multiple ranges into a single range of std::tuple
's (or pairs). This is nice, and precludes requiring implementing this ourselves, using boost::zip_iterator
or resorting to this kind of a hack*.
However, we also get std::ranges::zip_transform
. Why do we need it? After all , we can apply a ranges::views::transform
to a zipped range, can't we? So, isn't zip_transform
redundant?
* - that hack works well in C 11, and doesn't require tens of thousands of lines of code with concepts...
CodePudding user response:
If, in C , the concepts of "the ordered parameters of a function" and "a tuple" were identical or easily interchangeable, then you would be right.
... unfortunately, that is not the case. The difference is that std::ranges::zip_transform
cuts out std::tuple
's as the middle-man: Instead of constructing a tuple and passing it to the transform function, references to the range elements themselves are passed to the function!
So, instead of writing something like:
auto add = [](std::tuple t) {
return std::get<0>(t) std::get<1>(t) std::get<2>(t);
};
auto elementwise_sum =
std::views::zip(v1, v2, v3) | std::views::transform(add);
we can write, instead:
auto add = [](auto a, auto b, auto c) { return a b c; };
auto elementwise_sum = std::views::zip_transform(add, v1, v2, v3);
nicer, right?
CodePudding user response:
In addition to what @einpoklum has explained about zip_transform
, it is also worth noting that zip_transform
will always forward each elements in a zipped result to the function. Which means it cannot be used as a drop-in replacement for zip | transform
:
std::vector<int> v1, v2;
auto func = [](std::tuple<int, int> t){ return double{}; };
views::zip(v1, v2) | views::transform(func); // ok
// views::zip_transform(func, v1, v2); // this will not work
The second one will not work because it must receive a function that takes 2 parameters.
Sidenote, there are also views::adjacent
/views::adjacent_transform
, and their pairwise
specializations that behaves similar to zip
/zip_transform
.