的std :: for_each的工作迭代器的多个范围 [英] std::for_each working on more than one range of iterators

查看:158
本文介绍了的std :: for_each的工作迭代器的多个范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该拉姆达符号取得了STL算法更容易获得。我仍然在学习决定时,它的有用的,什么时候回落到良好的老式for循环。
通常情况下,有必要遍历相同大小的两个(或更多)的容器,以使得相应的元件是相关的,但由于某些原因未打包到同一类

The lambda notation has made stl algorithms more accessible. I am still learning to decide when it's useful and when to fall back to good old fashioned for-loops. Often, it becomes necessary to iterate over two (or more) containers of the same size, such that corresponding elements are related, but for some reason are not packed into the same class.

使用一个for循环来实现一个函数是这样的:

A function using a for-loop to achieve that would look like this:

template<typename Data, typename Property>
void foo(vector<Data>& data, vector<Property>& prop) {
    auto i_data = begin(data);
    auto i_prop = begin(prop);
    for (; i_data != data.end(); ++i_data, ++i_prop) {
        if (i_prop->SomePropertySatistfied()) {
            i_data->DoSomething();
        }
    }
}

为了使用的for_each,我需要一个版本,它能够处理多个范围;是这样的:

In order to use for_each, I need a version of it that handles multiple ranges; something like:

template<typename InputIter1, typename InputIter2, typename Function>
Function for_each_on_two_ranges(InputIter1 first1, InputIter1 last1, InputIter2 first2, Function f) {
    for (; first1 != last1; ++first1, ++first2) {
        f(*first1, *first2);
    }
    return f;
}

在这个版本中,上述code是这样的:

With this version, the above code would look like this:

template<typename Data, typename Property>
void foo_two_ranges(vector<Data>& data, vector<Property>& prop) {
    for_each_on_two_ranges(begin(data), end(data), begin(prop), [](Data& d, Property& p) {
        if (p.SomePropertySatistfied()) {
            d.DoSomething();
        }
    });
}

有没有使用STL算法实现相同的结果的等效方法是什么?

Is there an equivalent way of achieving the same result using stl algorithms?

修改

我发现的boost ::上的boost ::范围运行的for_each的形式确切回答我的问题。我加了答案,例如用code为完整起见。

I found the exact answer to my question in the form of boost::for_each running on boost::range. I added the answer, with example code for the sake of completeness.

推荐答案

1)在STL的算法并不意味着涵盖所有可能的情况下,如果你需要 for_each_on_two_ranges 然后写它(如你),并使用它。在STL的优点是它的扩展,因此,你已经用有用的新算法中扩展它。

1) The algorithms in the STL are not meant to cover every possible case, if you need for_each_on_two_ranges then write it (as you have) and use it. The beauty of the STL is it's so extensible, and you've extended it with a useful new algo.

2)如果不工作,你没有使用良好的老式for循环,可以用新奇的for循环,而不是!

2) If that doesn't work, you don't have to use good old fashioned for-loops, you can use fancy new for-loops instead!

作为另一个答案说,的boost :: zip_iterator 是你的朋友在这里,但它并没有将很难使用。下面是使用了与 zip_iterator

As another answer said, boost::zip_iterator is your friend here, but it doesn't have to be hard to use. Here's a solution using a range adaptor that is implemented with zip_iterator

template<typename Data, typename Property>
void foo(vector<Data>& data, vector<Property>& prop) {
    for (auto i : redi::zip(data, prop))
        if (i.get<1>().SomePropertySatistfied())
            i.get<0>.DoSomething();
}

拉链函数创建一个适配器开始()端()返回一个的boost :: zip_iterator成员,所以循环变量是每个基础容器中的元素的元组(并因为它是一个可变参数模板,你可以做任何数目的容器,这样你就不需要写 for_each_for_three_ranges for_each_for_four_ranges 等)

That zip function creates an adaptor with begin() and end() members that return a boost::zip_iterator, so the loop variable is a tuple of the elements of each underlying container (and as it's a variadic template you can do it for any number of containers, so you don't need to write for_each_for_three_ranges and for_each_for_four_ranges etc.)

您也可以使用的for_each

auto z = redi::zip(data, prop);
typedef decltype(z)::iterator::reference reference;

for_each(begin(z), end(z), [](reference i) {
    if (i.get<1>().SomePropertySatistfied()) {
        i.get<0>().DoSomething();
    }
});

这篇关于的std :: for_each的工作迭代器的多个范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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