如果我们有ranges::zip和views::transform,为什么我们需要ranges::zip_transform?

ein*_*ica 8 c++ idioms tuples std-ranges

在 C++23 中,范围(子)库已获得std::ranges::zip,它将多个范围压缩为单个范围std::tuple(或对)。这很好,并且不需要我们自己实现它,使用boost::zip_iterator或诉诸这种黑客*。

然而,我们也得到std::ranges::zip_transform. 为什么我们需要它?毕竟,我们可以将 a 应用于ranges::views::transform压缩范围,不是吗?那么,是不是zip_transform多余呢?


* - 该 hack 在 C++11 中运行良好,并且不需要数万行带有概念的代码......

ein*_*ica 10

如果在 C++ 中,“函数的有序参数”和“元组”的概念相同或可以轻松互换,那么您是对的。

... 不幸的是,事实并非如此。不同之处在于std::ranges::zip_transform省去了中间人:而不是构建一个std::tuple每个迭代器前进构建一个并将其传递给变换函数,而是对范围元素本身的引用传递给函数!

所以,不要写这样的东西:

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);
Run Code Online (Sandbox Code Playgroud)

我们可以这样写:

auto add = [](auto a, auto b, auto c) { return a + b + c; };
auto elementwise_sum = std::views::zip_transform(add, v1, v2, v3);
Run Code Online (Sandbox Code Playgroud)

我相信你会同意这更好。