2012-06-27 42 views
10

我正在制作一个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); 
} 

这是否意味着通过提供beginendoperator++,我可以有期望的行为?而且,这些方法应该做什么?我的意思是,我可以让他们懒惰而不打破东西吗?

+1

_“该数据当前来自数据库,并且不能完全适合内存”_因此,在不知道数据库的情况下很难提供更好的建议......但请记住,许多SQL数据库都提供了它们自己的内部迭代器机制_cursors_的形式可能对您有用。 – Rook

+1

我正在使用sqlite,但这可能会在将来发生变化,我不想向我的代码的用户公开原始指针,这就是为什么我试图封装它相当好(是的,已经很懒) API。 – Fabien

回答

11

差不多;如果在容器类中找不到beginend方法,编译器会查找其他几个位置以获取开始和结束迭代器;这是基于范围的循环在阵列上的工作方式,它没有beginend成员。它还将寻找ADL的免费功能beginend,最终还有std::beginstd::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节)。

+3

其实没有。它直接使用'.begin()'成员函数。如果没有找到这样的成员,它会通过ADL使用'begin',而不一定是'std :: begin'。 –

+0

@ R.MartinhoFernandes感谢您的澄清。 – ecatmur

+0

恩,谢谢,那正是我需要的。 – Fabien