2016-05-04 23 views
6

私は多くのことをベクトルし、次のようになり、いくつかのループがあります使用していますいくつかのコード修正しようとしています:ベクトルをクリアするにはどうすればよいですか?

for (int t=0;t<T;t++){  
    std::vector<double> vect; 
    for (int i=0;i<MAX;i++){ 
     double value; 
     vect.push_back(value); 
    } 
    /*....*/ 
} 

私は外側の反復のために同じベクトルを再利用することで、これを改善するために、多かれ少なかれ方法を知っているが、これを実行している間に私は実際に能力が変わらないことが保証されることを望んでいる間にstd::vector::clear"the vector capacity is not guaranteed to change"と呼んだときにそれを見つけました。多分私はcplusplus.comに書かれていることを誤解しているだけかもしれません。しかし、私の質問は次のとおりです。

どのようにして容量を変更せずにベクターをクリアすることができますか?

clearの後にreserveと呼んで容量を同じにする必要がありますか?

PS:だけ明確にするために、私は

std::vector<double> vect; 
vect.reserve(MAX); 
for (int t=0;t<T;t++){  
    for (int i=0;i<MAX;i++){ 
     double value; 
     vect.push_back(value); 
    } 
    /*....*/ 
    vect.clear(); 
} 

すなわちへのコードの上に書き直したいです。私はまだpush_backで記入したいのですが、私はclear()がベクターの容量を変更するのを心配しています。

+1

ここでは関連する議論があります。コンセンサスは、ベクトルのサイズ変更が容量に影響を与えてはいけないということです。 http://stackoverflow.com/questions/1624803/does-resizing-a-vector-invalidate-iterators – Roddy

+1

その答えに続く議論を読んだ後、より良い答えがhttp://stackoverflow.com/a/18467916 – Cubbi

+0

@Cubbiにありました私はかなり「クリア」は能力を変更することが許されていないと確信しているので、私の質問はちょっと古くなっています(そして、その時点ではcplusplusは間違っているようです)。私のレッスンは:標準以外の誰も信用しない;) – user463035818

答えて

4

はい、をclear()の後に呼び出します。最悪のケースでは、PODのベクトルの場合にはほとんど影響を及ぼさない単一の割り当て解除/割り当てが行われます。

+0

それはPODsではない。あなたが 'clear()'を呼ぶときにオブジェクト構築が起こっていません – Roddy

3

capacity()から返された値を保存し、reserve()メソッドを使用できます。

あなたにまったく同じcapacityを与えることを保証していない:

が大きいかnew_capに等しい だ値に、コンテナの容量を増やします。 new_capが現在のcapacity()より大きい場合は、 新しいストレージが割り当てられます。そうでない場合、メソッドは何も行いません。

int main() 
{ 
    vector<int> vec { 1,2,3,4,5 }; 
    size_t cap = vec.capacity(); 
    vec.clear(); 
    vec.reserve(cap); 

    cout << "vec capacity: " << vec.capacity() << '\n'; 
} 
+0

あなたはどこで引用をしましたか?特に、要求された容量が現在の容量よりも小さい場合は、何もしないことが本当に保証されているかどうか、私は興味があります。それほど重要ではありませんが、時には細部が問題になる場合があります – user463035818

+0

ああありがとう、私の引用ではcplreferenceとcplusplusが混在しているので、実際はちょっと混乱しました... – user463035818

-1

(必ずしもが、実装に応じて)clearが解放されます呼び出し、次にresizeを呼び出すと、高価な再配置をもたらすであろう。明白な答えはただベクトルものの反復すると0/NULLに結果を設定するには、次のようになります。

for(double& d : vect) 
{ 
    d = 0; 
    //d = NULL, depending on datatype 
} 

高価な再配分なしベクトルこれは単なる「クリア」します。この手順のパフォーマンスは要素の数に大きく依存しますが、これは簡単な方法です。

+0

私はサイズを変更したくありません。境界条件は次のとおりです。ベクタをクリアしてから、同じ容量まで 'push_back'で再び埋め込むことができるようにします。この申し訳ありませんでした場合は申し訳ありません – user463035818

+0

してください。それは私がそれを誤解しているようだ。ごめんなさい。 – calcyss

-1

もう一つの方法は、スワップトリックを行う操作を行うことであろう...

std::vector<double> vect = {0.1, 0.2, 0.3} 
{ 
    std::vector<double> swapVector; 
    swapVector.reserve(vect.capacity()); 
    vect.swap(swapVector); // swapVector now has the elements of vect 
          // vect has only reserved elements 
} // swapVector will be destroyed (including the elements that was in vect) 
std::cout << vect.capacity(); 
+0

"範囲外になるとvectはクリアされます"私は理解していません – user463035818

+0

@ tobi303 swapVectorがスタック上に作成され、vect内の要素と入れ替えられました。関数が範囲外になるとすぐにswapVectorは破壊され、その要素は...私の答えを編集させてください –

+0

私は、このアプローチには多くの欠点と利点がありません。あなたは割り当て解除と再配分を強制していますが(他の順ではありますが)、OPは避けたいものです。 – Roddy

6

cppreferenceは、ベクターの容量が変更されていないことを明示的に述べました。cppreferenceから

(太字強調それは私を所有している):

void clear(); 

は、コンテナからすべての要素を削除します。すべての参照、 ポインタ、または含まれている要素を参照するイテレータを無効にします。過去のイテレータを無効にすることがあります。
ベクトルのcapacity()を変更しません。

の式:a.clear()

戻り値の型

としてはstandardの容量を言及していない、コメントにドミトリー・クズネツォフが指摘

EDIT :void
アサーション/ノート前/後条件: aのすべての要素を破棄します。 aの 要素を参照するすべての参照、ポインタ、イテレータを無効にし、過去と最後のイテレータを無効にする可能性があります。

投稿: a.empty()はtrueを返します。

複雑さ:リニア。

+0

hmその場合、cplusplusはこれが保証されていないと主張しているので、標準が言うことは興味深いでしょう。 – user463035818

+0

それはcplusplusの入力ミスであり、 "変更が保証されていない"代わりに実際に "変更されないことが保証されている"ことを意味する可能性があります。 – user463035818

+0

疑義がある場合は標準を参照してください。とにかく、私はcplusplusに書かれていることを気にしません。 – Slava

関連する問題