33

私はstd::vectorいくつかのクラスの要素を持っていClassAます。std::map<key,ClassA*>さらに、いくつかのキー値をベクトルに含まれる要素へのポインターにマップするを使用してインデックスを作成したいと思います。

要素がベクトルの最後に追加されたとき(挿入されていないとき)に、これらのポインターが有効なままである(そして同じオブジェクトを指す)という保証はありますか?つまり、次のコードは正しいでしょうか。

std::vector<ClassA> storage;
std::map<int, ClassA*> map;

for (int i=0; i<10000; ++i) {
  storage.push_back(ClassA());
  map.insert(std::make_pair(storage.back().getKey(), &(storage.back()));
}
// map contains only valid pointers to the 'correct' elements of storage

std::list代わりに使用した場合、状況はどうstd::vectorですか?

4

7 に答える 7

28

ベクトル-いいえ。ベクトルの容量は決して縮小しないため、要素が削除または変更されても、操作された要素の前の位置を参照していれば、参照、ポインター、およびイテレーターは有効なままであることが保証されます。ただし、挿入すると、参照、ポインター、およびイテレーターが無効になる場合があります。

リスト-はい、要素を挿入および削除しても、他の要素へのポインター、参照、およびイテレーターは無効になりません。

于 2010-07-20T07:30:38.977 に答える
9

私の知る限り、そのような保証はありません。ベクトルに要素を追加すると、要素が再割り当てされ、マップ内のすべてのポインタが無効になります。

于 2010-07-20T07:28:28.890 に答える
7

使用してくださいstd::deque!要素へのポインタは、使用されている場合のみ安定していpush_back()ます。

注:要素へのイテレータは無効になる場合があります!要素へのポインタはそうではありません。

編集:この回答は理由の詳細を説明しています:push_front()の後にC++dequeのイテレータが無効になりました

于 2010-07-20T07:52:10.970 に答える
3

保証されているかどうかはわかりませんが、実際にstorage.reserve(needed_size)は再割り当てが発生しないようにする必要があります。

しかし、なぜインデックスを保存しないのですか?
インデックスを開始イテレータ(storage.begin()+idx)に追加することでインデックスをイテレータに変換するのは簡単です。また、最初に逆参照してからアドレス()を取得することで、イテレータをポインタに変えるのも簡単&*(storage.begin()+idx)です。

于 2010-07-20T07:44:24.560 に答える
1

コメントの1つから別の回答まで、必要なのはメモリ管理を一元化(容易化)することだけのようです。それが実際に当てはまる場合は、ブーストポインタコンテナライブラリなどの事前にパッケージ化されたソリューションの使用を検討し、独自のコードを可能な限り単純に保つ必要があります。

特に、見てくださいptr_map

于 2010-07-20T08:35:17.637 に答える
1

両方にポインタを格納させるだけで、不要なオブジェクトを明示的に削除できます。

std::vector<ClassA*> storage;
std::map<int, ClassA*> map;

for (int i=0; i<10000; ++i) {
  ClassA* a = new ClassA()
  storage.push_back(a)
  map.insert(std::make_pair(a->getKey(), a))
}
// map contains only valid pointers to the 'correct' elements of storage
于 2010-07-20T07:31:24.450 に答える
0
  1. ベクトル番号の場合。
  2. リストの場合はい。どうやって?イテレータは、リスト内の特定のノードへのポインタとして機能します。したがって、次のような任意の構造体に値を割り当てることができます。

    mylistを一覧表示します。

    pair <list :: iterator、int> temp;

    temp = make_pair(mylist.begin()、x);

于 2017-12-17T21:55:22.310 に答える