2012-06-27 27 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

ほとんど;コンパイラはコンテナクラスにbeginまたはendメソッドが見つからない場合、イテレータの開始と終了を取得するためにいくつかの場所を探します。これは、範囲ベースのforループが、beginendのメンバーを持たない配列でどのように動作するかです。また、無料の関数beginendをADLで検索します。最終的にはstd::beginstd::endとなりますので、範囲ベースのforループサポートを既存のコンテナに追加する機会がたくさんあります。 6.5.4項で詳細を説明します。

他の質問のために、イテレータは絶対に怠けることができます!良い例はstd::istream_iteratorです。です。これは、コンソールからの入力を読み込んだときに怠惰になることがあります。 ループでイテレータを使用する要件は、入力イテレータカテゴリ(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

関連する問題