2016-03-20 2 views
2

std::vectorのアイテムは動的に割り当てられ、再割り当てが発生するとそのアドレスが変更されることがあります。したがって、安定していないため、アドレスに依存することはできません。安定ベクトルのアイテムのアドレスを使用する

一方、いくつかのアイテムを含むstd::vectorがあり、そのライフサイクル中に何かを変更するつもりがない場合、そのアイテムのアドレスを使用することは有効です(明確に定義されていますか)。 ?

例:つまり

std::vector<foo> foos; 
foos.reserve(100); 
for(size_t i=0;i<100;++i){ 
    foos.emplace_back(make_random_foo()); 
} 
//From now no one can touch foos  
auto ptr_to_the_fifth_foo=&foos[4]; 

、私は私の自己であることをしなかったので、注目には、ベクトル項目のアドレスに影響する標準保証していますか?

+2

参照やイテレータを無効にするメンバ関数を使用しない限り、ポインタも無効にしません。 – Pixelchemist

+2

はい、これは、std :: vectorを使用していない限り動作します。 JVApen

答えて

3

std::vectorのメンバー関数が呼び出されていない場合、ベクトルはまったく変更されない可能性があります。したがって、内容は同じままであり、すべてのポインタは有効なままです。

operator[](size_type n)は、標準で*(a.begin() + n)に相当すると定義されています。

std::vectorは容器であり、したがって、容器の要件は、状態保持:特に断りのない限り、容器メンバ関数または通過を呼び出し、(明示的に、または他の機能の点で関数を定義することによって)

をライブラリ関数の引数としてのコンテナは、そのコンテナ内のオブジェクトに対してイテレータを無効化したり、その値を変更してはならない。

begin()はコンテナへのイテレータを無効にするために指定されていないため、operator[]もそのいずれにもなりません。

1

はい。

要素へのポインタと参照は、イテレータが無効になっている場合にのみ無効になります。

容量が大きくなる(サイズが容量を超えるとき)場合、またはベクトルにその要素がより前に、要素を挿入/削除すると、イテレータは無効になります。また、コンテナを移動または移動したときに無効にすることもできますが、発生しない可能性があります。

スワップがに指定されていないと思われます。イテレータを無効にする代わりに、「新しいホーム」を参照するようにします(したがって、「新しいベクター」の「新しい家」へのポインタ/ )(すなわち、バッファの所有権が変更される)。 Move-assignはこの約束をしません。もし私が頭の上から覚えているわけではありません。

+1

http://stackoverflow.com/a/25348988/1938348イテレータをあまりにも保存する必要がありますが、これはジェットの公式ではありませんが、 C++ 11にも遡及的に適用されます。なぜなら、それは「欠陥」と考えられていたからです。 – Yankes

+0

@Yankes提案された解決策は割り当て、建設だけをカバーしていませんか? – Yakk

+1

"http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2321に移動コンストラクタ(または移動割り当て[...])はありません – Yankes