如何使用带有两个范围的`transform()`的范围版本? [英] How to use the range version of `transform()` with two ranges?

查看:45
本文介绍了如何使用带有两个范围的`transform()`的范围版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标头< algorithm> 包含 std :: transform()的版本,该版本以两个输入序列,一个输出序列和一个二进制函数作为参数,例如:

The header <algorithm> contains a version of std::transform() taking a two input sequences, an output sequence, and a binary function as parameters, e.g.:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
    std::vector<int> v0{1, 2, 3};
    std::vector<int> v1{4, 5, 6};
    std::vector<int> result;
    std::transform(v0.begin(), v0.end(), v1.begin(), std::back_inserter(result),
                   [](auto a, auto b){ return a + b; });
    std::copy(result.begin(), result.end(),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

C ++ 20引入了 range算法,确实包括 std :: ranges :: views :: transform(R,F)及其实现 std::ranges :: views :: transform_view .我可以看到如何在一个范围内使用此 transform(),例如:

C++20 introduced range algoirthms which does include std::ranges::views::transform(R, F) and its implementation std::ranges::views::transform_view. I can see how to use this transform() with one range, e.g.:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <ranges>
#include <vector>

int main()
{   
    std::vector<int> v0{1, 2, 3}; 
    for (auto x: std::ranges::views::transform(v0, [](auto a){ return a + 3; })) {
        std::cout << x << ' ';
    }   
    std::cout << '\n';
}   

但是,没有支持多个范围的版本.因此,问题就变成了:如何在两个(或多个)范围内使用 transform()的范围版本?此方法的目标是从视图的惰性评估中受益,并避免创建中间序列(上述非范围版本中的 result ).可能的用法如下所示(将函数参数放在前面,以使可能的解决方案更容易允许甚至超过两个范围):

However, there is no version supporting more than one range. So, the question becomes: How to use the range version of transform() with two (or more) ranges? On objective of this approach is to benefit from the lazy evaluation of views and avoid the creation of an intermediate sequence (result in the non-ranges version above). A potential use could look like this (putting the function argument in front to make it easier for a potential solution allowing even more than two ranges):

for (auto v: envisioned::transform([](auto a, auto b){ return a + b; }, v0, v1) {
    std::cout << v << ' ';
}
std::cout << '\n';

推荐答案

使用 transform 的方式(使用任意数量的输入范围)是不可能直接使用的.从C ++ 20开始的< algorithm> .当然,您可以自己编写这种算法,而无需花费太多精力.

The way you would like to use transform, where you take an arbitrary number of input ranges is not possible directly with what's available in <algorithm> as of C++20. You can of course write such an algorithm yourself without too much effort.

具有2个输入范围的示例可以在C ++ 20中实现,如下所示:

The example with 2 input ranges can be implemented in C++20 like this:

std::ranges::transform(v0, v1,
                       std::ostream_iterator<int>(std::cout, " "),
                       std::plus{});    

这是一个演示,这是 transform 在此处列出.

Here's a demo, and this is specifically the last overload of transform listed here.

不幸的是,没有办法编写这样的等效版本:

There is unfortunately no way to write the equivalent version like this:

for (auto v : std::views::transform(v0, v1, std::plus{})) // no, unfortunately    
  std::cout << v << " ";

,但是上面的实现做同样的事情.当然,它满足您不必单独存储结果的要求;然后可以在生成时进行打印.

but the above implementation does the same thing. It certainly satisfies your requirements of not having to store the results separately; then can be printed as they're generated.

这篇关于如何使用带有两个范围的`transform()`的范围版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆