vectorのclear()とswap()の比較

5283 ワード

複数のオブジェクトが1つのvectorに存在するとします.
class Widget;
vector<Widget> vw;

その後、いくつかの理由でコンテナからいくつかのオブジェクト(erase-remove idiom参照)が削除されました.vectorおよびstringでは、erase()およびclear()はコンテナのcapacityを変更せず、メモリ使用量も変更しません.
swap()は、2つのコンテナの内容(Iterators,pointers,and references)を交換するために使用されますが、コンテナのcapacityを迅速に適切なサイズに調整することができます.
vector(vw).swap(vw);

巧みな点はvectorのコピー構造関数が有用な部分だけをコピーして占有されていない空間を無視し、このコピーで構築された容器でvwとswap()を行うことで、vwのcapacityを比較的小さい値に調整することができることである.
ここでsize()と絶対的に等しいのではなく相対的に小さい値というのは、コンテナのImplementationが構築時に自分で適切な値を選択して割り当てられた空間がすべての要素を十分に収容できることを保証するためであるが、この値はsize()よりも大きい可能性があるため、Item 14を参照することができる.
次に、vectorをいくつか操作し、erase、swap、clearの後のsizeとcapacityを出力する簡単な例を示します.
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int MAX = 1024;

#define show(v, msg)    printf ("%s -- %s: size: %lu, capacity: %lu
"
, \ #v, msg, v.size(), v.capacity()); int main(int argc, char *argv[]) { srand(time(NULL)); printf("Testing vector...
"
); vector<int> v; show(v, "After init"); v.reserve(MAX); show(v, "After reserve()"); for (int i = 0; i < MAX; ++i) { v.push_back(random()%1000); } show(v, "After Filling"); v.erase(remove_if(v.begin(), v.end(), [](int x){return x > 100;}), v.end()); show(v, "After erase()"); vector<int>(v).swap(v); show(v, "After swap()"); v.clear(); show(v, "after clear"); vector<int>().swap(v); show(v, "after swap with empty vector"); return 0; }

出力は次のとおりです.
Testing vector...
v -- After init: size: 0, capacity: 0
v -- After reserve(): size: 0, capacity: 1024
v -- After Filling: size: 1024, capacity: 1024
v -- After erase(): size: 106, capacity: 1024
v -- After swap(): size: 106, capacity: 106
v -- after clear: size: 0, capacity: 106
v -- after swap with empty vector: size: 0, capacity: 0
Program ended with exit code: 0