2009-10-08 5 views

答えて

18

号ベクトルの容量を縮小する唯一の方法は、スワップトリック

template< typename T, class Allocator > 
void shrink_capacity(std::vector<T,Allocator>& v) 
{ 
    std::vector<T,Allocator>(v.begin(),v.end()).swap(v); 
} 

であり、さらにそれは、標準に従って動作することが保証されません。

私が知っている限り、C++標準の次のバージョン(以前はC++ 0xだったものがC++ 1xになりました)は、 )はstd::vector<>::shrink_to_fit()になります。

+1

私は、このトリックに対して3つの理由から非常に助言します:1.機能は必ずしもそれが言っていることをするわけではありません。 2「最小の驚き」の原則を打ち破ります。3.潜在的に、移動するよりもコピーの潜在的な副作用について言えば、膨大なオーバーヘッドが発生します。 – einpoklum

+0

@einpoklum:ええと、これは動かず、したがって今日は最適ではありません。しかし、この答えは10年も経っているので、... – sbi

+0

@sbi:私はそれにも反対して助言します:-( – einpoklum

4

pop_back()はベクトルの容量を縮小しません。代わりに std::vector<T>(v).swap(v)を使用してください。

+0

@ sbiの答えの重複;そこで「スワップトリック」についての私のコメントを見てください。 – einpoklum

1

いいえ。 push_backと同じ、pop_backcapacity()には影響しません。それらはただsize()に影響します。

EDIT:

私はときv.size() < v.capacity()push_backは、容量を変更しないと述べている必要があります。

2

pop_XXXは容量を決して変更しません。 push_XXXは、容量以上のものをプッシュしようとすると容量を変更できます。ここ

1

はSTDのコード::ベクトル:: pop_back()

void pop_back() 
{ // erase element at end 
    if (!empty()) 
    { // erase last element 
     _Dest_val(this->_Alval, this->_Mylast - 1); 
     --this->_Mylast; 
    } 
} 

関数はデストラクタを呼び出し、最後の要素へのポインタを低下します。 VC(リリース)のコード。したがって、ベクトルの容量(または再割り当て)には影響しません。

+1

ある特定の実装は、標準が要求するものを決定するのに十分な情報ではありません。これは、質問する人が使用するのと同じ実装ではないかもしれません。 –

4

C++ 11では、予約された領域をベクトルの容量に縮小するために、shrink_to_fit()を呼び出してベクトル(デキューまたは文字列と同様に)を要求することができます。ただし、これは実装に依存していることに注意してください。これは単なる要求なので、何の保証もありません。次のコードを試すことができます:

#include <iostream> 
#include <vector> 
using namespace std; 

int main(){ 
    vector<int> myVector; 

    for (auto i=1;i!=1e3;++i) 
     myVector.push_back(i); 

    cout << "Capacity: " << myVector.capacity() << endl; 
    myVector.reserve(2000); 
    cout << "Capacity (after reserving 2000): " << myVector.capacity() << endl; 
    myVector.shrink_to_fit(); 
    cout << "Capacity (after shrink_to_fit): " << myVector.capacity(); 

}