2009-10-20 16 views
11

構造体のリスト(いくつかの整数を含む)を公開したいクラスがあります。 私はちょうどそれを反復処理し、それらに 例を読んで、外にはこれらのデータを変更する必要はありません:BOOST_FOREACHを使用してC++クラスを反復可能にする

struct TestData 
{ 
    int x; 
    int y; 
    // other data as well 
} 

class IterableTest 
{ 
    public: 
    // expose TestData here 
}; 

は今、私のコードで私はこのように私のクラスを使用します:

IterableTest test; 
BOOST_FOREACH(const TestData& data, test.data()) 
{ 
    // do something with data 
} 

私は既にこの記事を読んでいますhttp://accu.org/index.php/journals/1527 memberspacesについて。 しかし、すべてのTestDataを内部ベクトルなどに保存したくない(またはできない)ことはありません。 これは、クラス自体がストレージを所有していないためです。つまり、クラスによって直接アクセスできる基本のコンテナは実際には存在しません。クラス自体は外部コンポーネントにクエリして、次の要素、前の要素、またはi番目の要素を取得できます。

基本的に私のクラスにはコレクションがあるかのように動作しますが、実際にはクラスはコレクションを持たないようにします。 アイデア

+4

適切なイテレータを返すbegin/end関数を用意する必要はありませんか? – jalf

+0

はい、私はこれらのイテレータ – newgre

+0

を私に提供することができる基になるコンテナを持っていないので、あなた自身でそれを書いてください。 :) Boost.Iteratorライブラリは、すぐに起動して、すばやく実行する必要があります。 – jalf

答えて

5

独自のイテレータを記述する必要がありますように聞こえます。

Boost.Iteratorライブラリには、多数の有益なテンプレートがあります。私は、Iterator Facadeの基本クラスを数回使用しました。それを使用して独自のイテレータを定義するのは簡単ですばらしいです。

しかし、それがなくても、反復子はロケット科学ではありません。彼らは正しい演算子とtypedefを公開するだけです。あなたの場合、彼らは増分されたときに呼び出さなければならないクエリー関数の周りのラッパーになるでしょう。

イテレータクラスを定義したら、begin()end()メンバ関数をクラスに追加するだけで済みます。

基本的な考え方は、イテレータがインクリメントされたときにクエリ関数を呼び出して、次の値を取得する必要があるように思えます。 逆参照は、最後のクエリ呼び出しから取得した値を返します。

標準ライブラリstream_iteratorのセマンティクスの一部を見てみましょう。なぜなら、いくつかの怪しいものを回避する必要があるからです。「私たちは本当にコンテナを持っておらず、イテレータを作成できません現在のストリーム位置以外のどこにでも "問題が発生します。

たとえば、シーケンスの最後に達したときにNULLを返す関数query()を呼び出す必要があるとすると、「終了イテレータ」を作成するのは難しいでしょう。しかし、実際には、必要なのは、「イテレータが両方ともキャッシュされた値としてNULLを格納する場合、イテレータが等しい」ように等価を定義することだけです。したがって、 "end"イテレータをNULLで初期化してください。

入力イテレータに必要なセマンティクスを調べたり、Boost.Iteratorのドキュメントを読んでいる場合は、シングルパスイテレータを具体的に調べるのに役立ちます。おそらく、マルチパスイテレータを作成することはできません。ですから、シングルパスのイテレータにどのような振る舞いが必要かを正確に調べ、それに固執してください。ブーストFOR_EACHドキュメントページから

+0

そして私はいい人ですから:イテレータのコンセプトを入力>> http://www.sgi.com/tech/stl/InputIterator.html –

0

コレクションタイプで標準コンテナインターフェイスが使用されている場合は、BOOST_FOREACHをタイプに対応させるために何もする必要はありません。つまり、タイプにiteratorconst_iteratorのネストされたtypedefがあり、begin()end()のメンバー関数の場合、BOOST_FOREACHは既に自分のタイプに対して反復する方法を知っています。それ以上の措置は必要ありません。

http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/boost_foreach/extending_boost_foreach.html

+0

私はそれについて知っていますが、どこからそれらのイテレータを入手できますか?イテレータを使用できる基になるコンテナはありません – newgre

0

:シーケンス以上

BOOST_FOREACH反復します。しかし、配列としての資格は何ですか? BOOST_FOREACHはBoost.Rangeの上に構築されているので、Boost.Rangeがシーケンスとして認識する型を自動的にサポートします。具体的には、BOOST_FOREACHはSingle Pass Range Conceptを満たすタイプで動作します。たとえば、BOOST_FOREACHを次のように使用することができます。

関連する問題