2012-02-21 82 views
10

副本在閱讀代碼,我看到:交換向量與自身

vector<TypeA>(typeAObj).swap(typeAObj); 

我的問題是

爲什麼他們換一個向量與自身的副本?

+1

FWIW,[這是不_guaranteed_做任何事情](http://stackoverflow.com/questions/7829018/can-we-rely-on-the-reduce-capacity-trick)。 – 2012-02-21 15:12:34

+0

請注意,矢量不與*本身*交換,而是與本身的*副本*交換。 – 2012-02-21 15:14:31

+0

我寫了關於副本的文章,Rawicki編輯了它)) – 2012-02-21 15:18:44

回答

12

在C++ 03中,這是縮小到適合的模式,其中向量類的接口中沒有此類操作。代碼的作用是創建一個副本(希望該向量的capacity將接近可用元素的數量),然後將其與原始向量交換。表達式完成後,臨時(現在保存原始緩衝區)將被丟棄,並釋放內存。

考慮:

std::vector<int> large; 
large.reserve(10000000); // might be the result of multiple push_back/erase 
// large.capacity() >= 10000000 
large.push_back(1);  // Make more explicit that 'large' might not be empty 
std::vector<int>(large).swap(large); 
// large.capacity() is hopefully closer to 1 

在C++ 11的矢量類型已被修改,以提供一個shrink_to_fit的操作,需要在該角色。重要的是要注意,舊模式和shrink_to_fit都不是綁定操作,也就是說,除了capacity() >= size()之外的操作之後,無法保證該向量的capacity

+0

謝謝大衛!我確信這是一些副作用的伎倆。 – 2012-02-21 15:12:11

+0

「*除了capacity()> = size()*」之外的操作之後,向量的容量無法保證......爲什麼會這樣呢? – Nawaz 2012-02-21 15:15:20

+1

@Nawaz:就是這樣。 C++標準明確指出* shrink_to_fit *是一個不具約束力的調用,並聲明沒有這種保證。在這種模式中,同樣的情況發生,在標準中沒有任何地方需要拷貝不具有相同的*容量*或甚至比原始對象更多。對'capacity()'的唯一要求是,由於顯而易見的原因,它必須至少是size()。除此之外,這個習語在很多實現中都起作用,如果它比這個尺寸大得多,就會減少容量。 – 2012-02-21 15:18:53

8

我相信這是一種將矢量「縮小」到最小尺寸的方法。

vector<TypeA>(typeAObj)創建保留大小可能小於原始大小的矢量的副本。

因此用一個新的副本交換矢量可能是一種釋放一些不受歡迎的內存的方法。