我正在使用Visual Studio 2012,所以C ++ 11大部分都可以...... 提升也很好,但我宁愿避免使用其他的libreries,至少不是widley使用过的。
我想以最优雅的方式创建一个只返回无限序列的前向迭代器。例如,所有自然数的序列。
基本上我想要这个f#代码的C ++等效:
let nums =
seq { while true do
yield 1
yield 2
}
上面的代码基本上创建了一个返回[1; 2; 1; 2 ...]
的枚举器我知道我可以通过编写课程来做到这一点,但是所有新的lambdas都需要更短的方式......
答案 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包含用于将一个迭代器输出转换为另一个相关输出的工具。您可以使用它来重复循环来自两项容器的元素(在您的情况下包含元素1
和2
)。
答案 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 << ' ';
}