2016-10-14 5 views
0

私はいくつかのデータを受け取るために(ネットワークを介して)サービスに接続するクラスを設計しています。私は、私が事前に受け取る人データポイントがどのようになっているのか分かりません。それにもかかわらず、もしこのクラスを完全な栄光でSTLを楽しむためにforward_iteratorを使って反復可能にする方法があるのであれば、私は不思議に思っていました。私は、これはまだやることが可能何とかであれば、私は、好奇心が強い、有効なend()を提供することができないとして、しかしForward iterator with moving end()

self_type operator++() { 
    // if there are some locally cached data points left return next 
    // else connect to service again to receive the next batch of data 
} 

:私の考えのようなものでした。明らかに、任意のSTLアルゴリズムでは動作しません

bool hasMoreDataPoints() const; 
DataPoint& getNext(); 

代替(およびイテレータレス)インタフェースは、おそらくのようになります。

+1

ストリームのようにイテレータを実装する必要があり、 'end'は単なるデフォルトのイテレータであると思えます。 – NathanOliver

答えて

4

istream_iteratorを標準ライブラリとして使用します。データが不足したときは、そのタイプのデフォルトで作成されたオブジェクトと同じになるように反復子状態を設定します。そしてあなたのend()相当品があります。

+0

詳しいことはありますか?だから、私はまだstd :: iteratorから継承し、簡単な方法でインターフェイスを実装しますが、 'end()'関数の中で等しいかどうかのチェックをしますか? – NewProggie

+1

@NewProggie 'std :: iterator'から継承しないでください。C++では廃止予定です。 – KABoissonneault

+2

@ KABoissonneault - それは2016年だけです。あなたがそのアドバイスをしているなら、代わりに何をすべきかを説明する必要があります。 –

0

キャッシングのためにクラス内で使用するストレージがあるとします。 a std::vectorstd::begin()std::end()イテレータを(すべての通常の形式で)公開することができます。アルゴリズムは、基になるコンテナを直接操作し、operator++,operator==などのコンテナイテレータのメンバ関数を使用します。

ロジックをさらに導入する必要がある場合は、カスタムイテレータを作成する必要があります。これは、基本的にコンポジションで行うことができます。つまり、ストレージコンテナに対応するイテレータを含む新しいクラスを作成し、それに応じて必要なすべての機能を公開します。


EDIT:

struct DataPoints 
{ 
    std::list<double> _list; 
    auto begin() const 
    { 
     return _list.begin(); 
    } 
    auto end() const 
    { 
     return _list.end(); 
    } 
    //other versions: non-const begin and end, cbegin, cend 
} 

単純なアプローチのためにすでにそれだ:あなたがリストを使用言ったように。

DataPoints d; 
std::find(d.begin(), d.end(), 10.0); 

と同じように、より多くのロジックが必要な場合は、おそらくカスタムイテレータを作成する必要があります。

私は有効なエンドを()を提供することはできませんしかし
+0

基になるコンテナを変更するときにイテレータの無効化を避けたいので、ここではstd :: listを使用します。どのように私はstd :: list iteratorの実装を適応させるでしょうか? – NewProggie

+0

それはあなたが望むものによって異なります。 DataPointsをループしたり、標準ライブラリアルゴリズムを適用したりするだけの場合は、上記のとおりです。リストイテレータ機能を拡張する内部イテレータコンポーネントにさらなるロジックが必要な場合は、上記で十分ではありません。たとえば、 '演算子++ 'をデータの上に無作為に移動させたい場合です。そのような場合は、独自のイテレータを記述する必要があります。 – davidhigh

+0

ところで、実装を前方イテレータに制限する必要はありません(あなたが質問のタイトルで述べているように)。一般的には、基になるコンテナと同じイテレータカテゴリを使用する必要があります。 – davidhigh

0

、これはまだ何とか可能であるならば、私は、好奇心が強い....

あなたはそのコンテナクラスのいずれかを使用することができますSTLが付属しています。 ベクトルまたはリストまたは他の適切なコンテナを使用しているとします。 STLで提供されているものを使用して独自のラッパーを書く

vector<datapoint> mydpvector; 

//as data comes in 
mydpvector.push_back(newdp); 

vector<datapoint>::const_iterator cit=mydpvector.begin(); 
//now iterate everytime over the container 

for(cit;cit!=mydpvector.end();cit++) 
{ 
//get the data you need 
} 

//alternately if you need just the last element do this 
mostrecentdp = mydpvector.back();