MyGenerator 表示(可能)有限的整数序列,计算成本很高。所以我不想预先生成它们并将它们放入容器中。
struct MyGenerator{
bool HasNext();
int Next();
}
要打印全部:
MyGenerator generator;
while (generator.HasNext()) {
std::cout << generator.Next() << std::endl;
}
如何实现一个遵循forward_iterator协议的类似生成器?
boost::function_input_iterator http://www.boost.org/doc/libs/1_50_0/libs/iterator/doc/function_input_iterator.html很接近,但我不知道前面的元素数量。
首先,看一下实现boost::function_input_iterator
,因为您想要的是相同的,只是必须修改迭代器的相等性测试,以应对您不知道它是否是无限的以及如果不是的话有多少项的事实。一旦您习惯了这种风格,Boost 的作者将通过他们的代码为您提供比我更好的建议:-)
也就是说,沿着这些思路(未经测试):
template <typename Generator>
struct generator_iterator : iterator<forward_iterator_tag, int> {
generator_iterator(const Generator &gen, end = false) : count(0), gen(gen), last_val(0), is_end(end) {
if (!end) advance();
}
void advance() {
if (gen.HasNext()) {
lastval = gen.Next();
} else {
is_end = True;
}
count += 1;
}
int operator *() {
return lastval;
}
generator_iterator &operator++() {
advance();
return *this;
}
generator_iterator operator++(int) {
generator_iterator result = *this;
advance();
return result;
}
bool operator==(const generator_iterator &rhs) {
return (is_end && rhs.is_end) || (count == rhs.count);
}
bool operator!=(const generator_iterator &rhs) {
return !(*this == rhs);
}
size_t count;
Generator gen;
int lastval;
bool is_end;
};
- 原则上,计数可以换行,尽管您只需要在较小的实现上担心这一点
size_t
,因为 64 位在实践中永远不会换行。为了安全起见,您可以使用不同的类型来计数:uint64_t
或者如果所有其他都属于用户定义的大整数类型。咨询std::iterator
不过,文档,因为一旦你的迭代器运行时间超过size_t
你想给它一个非默认值difference_type
.
- 方式
Generator
必须是可复制的(并且副本必须与原始版本具有相同的状态,并且此后两者必须独立前进),否则您没有机会实现forward_iterator
除了存储发电机可能无限量的输出之外。如果您只需要一个input_iterator
那么你可以参考Generator
引用。
- 如果您不需要包装以前的
MyGenerator
,而不是你只想知道如何编写一个可能无限的迭代器,那么你可以摆脱模板参数,在迭代器中存储你喜欢的任何状态,然后只需将代码放入以推进状态advance()
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)