私は値をオンデマンドで生成するイテレータDataIterator
を持っているので、参照解除演算子はデータ&ではなく、データを返します。 dataIteratorをreverse_iteratorでラップして逆にしようとするまでは、それは問題ないと思いました。オンデマンドイテレータを反転する
DataCollection collection
std::reverse_iterator<DataIterator> rBegin(iter) //iter is a DataIterator that's part-way through the collection
std::reverse_iterator<DataIterator> rEnd(collection.cbegin());
auto Found = std::find_if(
rBegin,
rEnd,
[](const Data& candidate){
return candidate.Value() == 0x00;
});
上記のコードを実行すると、値が0に等しいDataオブジェクトは検出されません。私が述部の中にブレークポイントを置くと、私は決して0xCCCCのように見えない奇妙な値を見るでしょう - おそらく初期化されていないメモリでしょう。何が起こるかというとreverse_iteratorの間接参照演算子は、このようになっていることである(xutilityから - のVisual Studio 2010)
Data& operator*() const
{ // return designated value
DataIterator _Tmp = current;
return (*--_Tmp); //Here's the problem - the * operator on DataIterator returns a value instead of a reference
}
問題がどこにある最後の行がある - 一時的なデータが作成されますし、そのデータへの参照が返されます。参照はすぐに無効です。
(constデータ&候補)の代わりに(データ候補)std :: find_ifで述語を変更すると、述語が機能しますが、私はそこで未定義の動作をしているだけです。参照は無効ですが、メモリが壊れる前にデータのコピーを作成しています。
どうすればよいですか?そのオペレータは*ではなくデータのデータ&を返すよう
- は私DataIteratorを修正しますか?私はこれがどのように可能であるか実際見ていない。データ&の代わりにデータを返すDataIterator全体のポイントは、非圧縮データセット全体をメモリに保持する余地がないためです。必要に応じて表示するアイテムを作成します。
たぶん、私は '現在の'データ値を保持することができますが、その参照はDataIteratorをインクリメントまたはデクリメントすると無効になります。編集one of the answers suggests a shared_ptr - reverse_iteratorの特殊化を作成し、その参照解除演算子を参照ではなく値を返すようにしますか?これは不便な作業のようですが、STLの残りの部分ではなく、ここでうまく動作しないDataIteratorなので分かります。
- 同じ行に沿って、reverse_iteratorに特化したfind_ifを作成するよりも、逆になるfind_ifを作成するほうが簡単かもしれません。
- 私は
と考えていない何か他のものは、彼らが今から6ヶ月同じことをしようとすると、何が間違って考え出す半日を吹いてから、他の誰かを防ぐことができます私はDataIteratorに行うことができます何かありますか?
に
を変更すると、なぜあなたは、このタスクのためのイテレータを選んだのですか? –
データを 'ベクトル'にコピーし、そのベクトルに 'reverse_iterator'を使用します –
基礎となるデータが非常に大きいが圧縮されているため、イテレータが選択されました。イテレータは、反復処理を行う際に、一度に1つずつデータを解凍します。これにより、データセットを見ることができ、複数の非常に大きなデータセットをメモリに保持しなくても、派生したデータセットを遅延生成することができます。 –