我正在制作一个产生大量数据的C ++ 11类。该数据目前来自数据库,并不能完全适合内存。我想为用户提供一个迭代器,其行为类似于常规的STL迭代器,但这将是懒惰的。更确切地说,我可以做类似的事情:
for (auto& item : big_bunch_of_data) {
do_stuff_with(item);
}
仅在每次迭代时从数据库中检索项目。如果我是对的,这个新语法就是糖
for (stuff::iterator it = big_bunch_of_data.begin();it != big_bunch_of_data.end();it++) {
do_stuff_with(*it);
}
这是否意味着通过提供begin
,end
和operator++
,我可以获得所需的行为?而且,这些方法应该做什么?我的意思是,我可以让它们变得懒惰而不会破坏它们吗?
答案 0 :(得分:11)
几乎;如果在容器类中找不到begin
或end
方法,编译器将查看其他几个地方以获取开始和结束迭代器;这就是基于范围的for循环如何在数组上工作,没有begin
和end
成员。它还会查找ADL的免费函数begin
和end
,最终std::begin
和std::end
,因此有很多机会可以改进基于范围的循环支持容器。第6.5.4节涵盖了细节。
对于你的其他问题,迭代器绝对可以是懒惰的!一个很好的例子是std::istream_iterator
,当从控制台读取输入时, 是懒惰的。
在for
循环中使用迭代器的要求是它应该满足输入迭代器类别,如第24.2.3节所述;该类别所需的操作为!=
,一元*
以及增量前后++
。
为了让语言知道你已经创建了一个输入迭代器,你应该从std::iterator<std::input_iterator_tag, T, void, T *, T &>
继承,其中T
是你的迭代器所处理的类型(见第24.4.3节)。