如何在C ++中创建无限序列

时间:2013-11-28 11:25:45

标签: c++ boost c++11

我正在使用Visual Studio 2012,所以C ++ 11大部分都可以...... 提升也很好,但我宁愿避免使用其他的libreries,至少不是widley使用过的。

我想以最优雅的方式创建一个只返回无限序列的前向迭代器。例如,所有自然数的序列。

基本上我想要这个f#代码的C ++等效:

let nums =
    seq { while true do
            yield 1
            yield 2
        }

上面的代码基本上创建了一个返回[1; 2; 1; 2 ...]

的枚举器

我知道我可以通过编写课程来做到这一点,但是所有新的lambdas都需要更短的方式......

6 个答案:

答案 0 :(得分:4)

这就是你想要的:

#include <iostream>
#include <vector>

int main() 
{
    auto nums = []
    {
        static unsigned x = 2;
        return ( x++ % 2 ) + 1;
    };

    std::vector< int > v{ nums(), nums(), nums(), nums(), nums() };
    for( auto i : v )
    {
        std::cout << i;
    }

    return 0;
}
或者我误解了这个问题?

答案 1 :(得分:3)

我写了一个名为Pipeline的库,使用它可以轻松地编写这样的内容,如:

auto infinite_seq = generate(1, [](int i) { return (i % 2) + 1; });

现在infinite_seq延迟范围,这意味着它将生成值并在 时为您提供 。如果您要求10值,则会生成完全10个值 - 这可以表示为:

auto values = infinite_seq | take(10);

或者你可以这样写:

auto values = generate(1, [](int i) { return (i % 2) + 1; }) | take(10);

for(auto i : values) 
      //working with i

查看generate的文档。

答案 2 :(得分:3)

更简单的事情,如果你可以依赖于提升就是写下这样的东西:

int i = 0;
auto gen = boost::make_generator_iterator([=]() { return i++; });

C ++ 14版本:

auto gen = boost::make_generator_iterator([i=0]() { return i++;});

文档为here

P.S。:我不确定它是否可以在没有result_type成员的情况下工作,C ++ 03仿函数需要它。

答案 3 :(得分:2)

标准C ++没有真正的迭代器生成器,可以帮助您避免手动编写类。您可以查看我的range library这样的迭代器生成器。这段代码基本上允许你编写

for (auto i : range(1))
    …

生成无限序列1,2,3,.... Boost.Iterator包含用于将一个迭代器输出转换为另一个相关输出的工具。您可以使用它来重复循环来自两项容器的元素(在您的情况下包含元素12)。

答案 4 :(得分:0)

当你手上拿着一把锤子时,周围的一切看起来像钉子。 Lambdas和其他C ++ 11功能确实很酷,但您应该选择有效的工具来解决问题。在这种情况下,我发现没有比带有重载运算符的短类更简单,更优雅的东西:

class MyInfiniteIter
{
private:
    unsigned int i;

public:
    MyInfiniteIter()
    {
        i = 0;
    }

    int operator *() {

        return i;
    }

    int operator++ () {

        i++;
        if (i == 10)
            i = 0;

        return i;
    }
};

int main(int argc, char * argv[])
{
    for (MyInfiniteIter i;; ++i)
    {
        printf("%d\n", *i);
    }
}

答案 5 :(得分:0)

这是C ++ 14 index_sequence来帮助:

#include <iostream>
#include <vector>

namespace std
{
   template< int ...i> struct index_sequence{};

   template< int N, int ...i>
   struct make_seq_impl : make_seq_impl< N-1, N-1,i...> {};
   template< int ...i>
   struct make_seq_impl<0,i...>{ typedef index_sequence<i...> type; };

   template< int N > 
   using make_index_sequence  = typename make_seq_impl<N>::type;

} // namespace std


typedef std::vector<int>  integer_list;

template< typename F, int ...i >
integer_list make_periodic_list_impl(F f, std::index_sequence<i...> ) 
 {     
        //      {  1 2 1 2 1 2... }
        return {  f(i) ... };
 }

template< int N , typename F>
integer_list make_periodic_list(F f) 
{
   return make_periodic_list_impl(f, std::make_index_sequence<N>{} );
}



 int main()
 {
   std::vector<int> v = make_periodic_list<20>([](int i){return 1 + (i&1);}); 

     for( auto e : v ) std::cout << e << ' ';
 }