std::vector是順序容器,當用erase成員函數刪除一個迭代器指向的元素時,會自動移動(不是std::move)後面的元素到前面來,而迭代器的指向不變(如果是std::map、std::list這類關聯型容器,迭代器會失效),並且不會回收內存(也就是capacity不會變)。當用swap成員函數跟自身的拷貝交換時,才能釋放多餘內存。
代碼如下,自定義一個foo類以監視構造、賦值、複製、移動、析構等情況。
#include <iostream>
#include <vector>
class foo{
int a;
public:
foo(int x=0):a(x){std::cout<<a<<" is constructed\n";}
foo(foo &&from){a=std::move(from.a);std::cout<<a<<" is moved\n";}
foo(const foo& from){a=from.a;std::cout<<a<<" is copied\n";}
foo& operator=(const foo&from){
std::cout<<a<<" is assigned by "<<from<<"\n";
if(this == &from)return *this;
a=from.a;
return *this;
}
foo& operator=(foo &&from){
std::cout<<a<<" is move-assigned by "<<from<<"\n";
a=std::move(from.a);
return *this;
}
friend std::ostream &operator<<(std::ostream&o,const foo&f){o<<f.a;return o;}
operator int(){return a;}
~foo(){std::cout<<a<<" is destructed\n";}
};
int main(){
/*1*/std::vector<foo> vec = {0,0,1,2};
std::cout<<"Go through:\n";
std::cout<<"Capacity:"<<vec.capacity()<<std::endl;
for(auto& v:vec) /*printf("%d\n",v);*/std::cout<<v<<std::endl;
std::cout<<"Erase:\n";
for(std::vector<foo>::iterator iter=vec.begin();
/*2*/ iter!=vec.end();/*iter++*/){
if(*iter == 0){
std::cout<<"Erasing:\n";
/*3*/ vec.erase(iter);
std::cout<<"Erased.\n";
}
else/* printf("%d\n",*iter);*/std::cout<<*iter++<<",";
}
std::cout<<"\nGo through again:\n";
std::cout<<"Capacity:"<<vec.capacity()<<std::endl;
for(auto& v:vec) /*printf("%d\n",v);*/std::cout<<v<<std::endl;
std::cout<<"Swapping:\n"<<std::endl;
/*4*/ std::vector<foo>(vec).swap(vec);
std::cout<<"Capacity after swapping:"<<vec.capacity()<<std::endl;
return 0;
}
運行情況如下(在VS 2010 和 VS 2017上跑會出錯,在Linux下沒問題。不知道爲什麼這篇文章不能繼續加字了。。。