代码之家  ›  专栏  ›  技术社区  ›  Jonathan Mee

是否有一个标准的算法在一个范围内迭代?

  •  0
  • Jonathan Mee  · 技术社区  · 10 年前

    我需要调用lambda int 在一定范围内。有没有一种标准算法可以做到这一点?

    理想情况下是等效的:

    for(auto i = 13; i < 42; ++i)[](int i){/*do something*/}(i);
    
    3 回复  |  直到 10 年前
        1
  •  4
  •   Lightness Races in Orbit    10 年前

    没有内置的,没有。

    你可以用手工制作的迭代器自己完成 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 )

        2
  •  3
  •   Praetorian Luchian Grigore    10 年前

    我不知道标准库中有什么东西可以像您所要求的那样按需生成一系列数字。但这可以通过使用Boost的两种不同方式实现。

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

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

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

    Live demo

        3
  •  1
  •   Community CDub    7 年前

    正如其他答案所提到的,如果Boost是一个选项,那么有更好的方法来实现这一点。如果没有,最好的方法是在最初的问题中:

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

    然而,未来是光明的, chris has mentioned 提议 N4128 这建议将范围与迭代器一起纳入标准。

    现在,草案仍处于早期阶段,因此在确定如何使用之前,需要进行大量澄清。但其中一个概念是,所有STL算法都将过载 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*/});
    

    这将导致 生成_n 被调用28次(13+28=41) 看法 将提供这些数字的迭代,并将它们输入到 用于每个(_E) .

    chris has suggested 而不是 生成_n 修改 极少量 可能会起作用: iota(13, 41) 关键是要注意,无论使用什么,都必须有一个结束条件,因为视图 懒散地 调用生成器,直到不再请求项目。所以这个 for_each(view::iota(10), [](int i){/*do something*/}); 定义了无限循环。