是否有标准算法来迭代范围?

时间:2015-03-01 00:09:09

标签: c++ algorithm for-loop range standard-library

我需要在范围内调用每个int的lambda。是否有标准算法可以做到这一点?

理想情况下等同于:

for(auto i = 13; i < 42; ++i)[](int i){/*do something*/}(i);

3 个答案:

答案 0 :(得分:3)

没有内置的,没有。

您可以使用手工制作的迭代器和std::for_each自行完成,或使用Boost's counting iterators帮助您:

#include <boost/iterator/counting_iterator.hpp>
#include <algorithm>
#include <iostream>

int main()
{
    std::for_each(
        boost::counting_iterator<int>(13),
        boost::counting_iterator<int>(42),
        [](int i){ std::cout << i << ' '; }
    );
}

输出:

  

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

live demo

答案 1 :(得分:3)

我不知道标准库中的任何内容可以像您要​​求的那样按需生成一系列数字。但是使用Boost可以通过几种不同的方式完成。

  1. 使用Boost.Range生成整数范围,并使用范围版本for_each

    boost::for_each(boost::irange(13, 42), [](int i){ std::cout << i << ' '; });
    
  2. 使用Boost.Iterator中的boost::counting_iterator并将其传递给std::for_each

    std::for_each(boost::make_counting_iterator(13),
                  boost::make_counting_iterator(42), 
                  [](int i){ std::cout << i << ' '; });
    
  3. Live demo

答案 2 :(得分:1)

正如其他答案所提到的,如果Boost是一个选项,那么有更好的方法可以做到这一点。如果没有,最好的方法是在原始问题中:

for(auto i = 13; i < 42; ++i)[](int i){/*do something*/}(i);

但是,未来很明亮,chris has mentioned提案N4128建议将范围与迭代器一起纳入标准。

现在草案仍然处于早期状态,因此需要进行大量澄清才能确定如何使用该草案。但其中一个概念是所有STL算法都会被重载以获取view s,这是一个瘦包装器,提供对包含元素的访问,但也是一个智能的结束位置。

虽然选择展示view强大功能的更复杂的示例,但Motivation and Scope中作者的示例使用了iota,这正是我们想要的:

int total = accumulate(view::iota(1) |
                       view::transform([](int x){return x*x;}) |
                       view::take(10), 0);

出于我们的目的,我们需要在generate_n算法中使用for_each

for_each(view::generate_n(28,[]{static int i = 13; return i++;}),[](int i){/*do something*/});

这会导致generate_n被调用28次(13 + 28 = 41),创建的view将提供对这些数字的迭代,将它们输入{{1}中的原始lambda中}。

chris has suggested而不是for_each修改generate_n可能会有诀窍:iota关键是要注意所使用的内容必须具有结束条件,因为view lazily 调用生成器,直到不再请求任何项目。所以这个 iota(13, 41) 定义了一个无限循环。