私はstd::vector
のカスタムクラスを持っています(簡略化のため、サンプルではint
を使用しています)。私はベクトルのメンバに参照/ポインタ/リンク/その他を保持したいと思います。ただし、ベクターには要素が削除されて追加されることがよくあります。ベクターへの変更後、ベクトル要素への参照/ポインタ/リンクを維持する方法は?
私の要点を説明するために、以下のサンプルでは、参照またはベクトルの2番目の要素へのポインタのいずれかを取ります。私は参照/ポインタを使用して、選択した要素の値を増やします。最初の要素を消去し、ref /ポインタを使って再度インクリメントします。
参考例:
std::vector<int> intVect = {1,1,1};
int& refI = intVect.at(1);
refI++;
intVect.erase(intVect.begin());
refI++;
スマートポインタの例:私は起こるしたい何
std::vector<int> intVect2 = {1,1,1};
std::shared_ptr<int> ptrI = std::make_shared<int>(intVect2.at(1)) ;
*ptrI = *ptrI +1;
intVect2.erase(intVect2.begin());
*ptrI = *ptrI +1;
は3の値を持つように参照される要素で終わるし、最終的なベクター{3,1}
で構成されています。しかし、参考例では、最終ベクトルは{2,2}
であり、ポインタ例では最終ベクトルは{1,1}
である。
ポインタが本質的にメモリアドレスであることを理解すると、なぜこの方法が不可能なのか理解できますが、どういうわけか、私に教えてください。
さらに重要な質問は、実行可能な要素(値またはオブジェクト)にref/pointer/link/otherの何らかの形式を許可する代替アプローチまたは構造を使用できますそれを含むベクトル(または他の構造)にメンバーを追加したり、メンバーを削除したりした後余分な信用のため
:私は実際に働いている
オブジェクトがposition
性質を持っています。どのオブジェクトがどの位置にあるのかをすばやく調べるためにオブジェクトを追跡する必要がある2番目の構造があります。私は現在、可能な位置を表すためにグリッド(ベクトルのベクトル)を使用しています。それぞれの位置は、現在その位置にあるオブジェクトのオブジェクトのベクトルにインデックスを保持しています。しかし、オブジェクトがベクターから削除されると(非常に頻繁に起こり、反復ごとに数百回まで)、私の現在の措置は、すべてのグリッド位置をループし、削除されたインデックスよりも大きなインデックスを減らすことです。これは遅くて不器用です。文脈におけるこの問題に関する追加の考えは高く評価されるが、私の重要な質問は上記の例に関係する。
'消去(開始)は'すべてのイテレータ、ポインタ、および参照を無効にするのであなたの二つの例がUBです。イテレータではなく、_index_を保存して、必要に応じて調整することはできますか?私は最近、私が使用していたイテレータを無効にする危険性があることを知ったところで同様の問題を抱えていました - そして、再割り当てなどを心配する年齢を過ごした後で、必要な要素がどの要素がインデックスであるかあなたのケースは、後でそれに戻るために)でした。だから、ベクトルが再割り当てされたかどうかは今や問題ではなく、私のコードはうまく動作します。 –
@underscore_dまた、 'erase'の後にインデックスが無効になることがある(または有効であるが、別の要素にインデックスする) – mvidelgauz
@mvidelgauzはい、私はOPがインデックスの調整方法を知っていると言って編集しました。これは、バッファ全体が操作中に移動された可能性があるため、イテレータまたはポインタを後で調整できると仮定するのではなく、定義された動作です。 –