Effective STL 條款17

Item17 使用"swap詭計"來修去多餘的空位

假設現在你正在爲電視遊戲節目"Give Me Lots Of Money--Now!"寫一個支持軟件.你一直記錄着潛在的競爭者,
你把他們保存在一個vector中:

class Contestant {...};
vector<Contestant> contestants;

當節目組選擇新的競爭者,它會被申請信淹埋,而你的vector將很快申請很多元素. 當節目製作人挑選期望的競爭
者,當然只有很少一部分競爭者來到vector的前部(也許通過partial_sort或partition參考Item31),不需要的競爭
者將被刪除出vector(典型地使用區間刪除,參考Item5).它可以很好的減小vector的大小(size),但對vector的空間
(capacity)不起任何作用.如果vector一次包含了10萬個競爭者,它的空間將保持最少100000,即使後來它只保存,嗯,
也許10個.

爲了避免vector佔用它不再使用的空間,你需要減少它的空間,從它用過的最大空間到它現在僅需的空間.這種
空間減少通常稱爲"收縮至合適"(shrink to fit).收縮至合適易於編程,但是代碼是--如何實現--事情並非如
直覺所想.讓我先展示它,等一下再說明.

這是如何從競爭者vector中修去多餘空位的方法:

vector<Contestant>(contestants).swap(contestants);

表達式vector<Contestant>(contestants)創建一個臨時的vector,它是contestants的拷貝:vector的拷貝構造函數
完成這一工作.但是vector的拷貝構造函數僅申請適合需要的空間來複制.因此臨時vector不包含多餘空位.然後
交換臨時對象和contestants的數據,結果臨時對象包含着過多的空間,這些空間曾經是contestants的,
最後,臨時對象銷燬,並釋放空間.Yes,收縮至合適.

同樣的技巧也適用於string:

string s;
…   //make s large, then erase most
  //of its characters
string(s).swap(s); // do a "shrink-to-fit" on s

現在, 語言警察要求我通知你,並沒有什麼人保證這一技巧真的減少了多餘的空間.實現可以自由的賦與vector或string
多餘的空間,如果它願意,並且有時它確實願意.例如,有一個最小的空間值,低於此值,將不再減少.也可能強制要求
vector和string的空間必須是二的倍數.(根據我的經驗, 這種不規則的要求,在string的實現中更常見,而不是vector)
例如Item15).這種方法的收縮至合適並不表示"使用空間儘可能的小",它表示"使用空間盡實現願意,達到的當前容器大小
換一個STL實現也許更小,但是,這是你能做地最好情況.因此當你想起vector或stirng的"收縮至合適",想想"swap詭計"

另一方面,一個"swap詭計"的變體可以用於即清空容器又減少它的大小至實現許可的範圍.簡單地與默認構造函數生成
的臨時對象交換數據即可:

vector<Contestant> v;
string s;
…     // use v and s
vector<Contestant>().swap(v);   //clear v and minimize its capacity
string().swap(s);   // clear s and minimize its capacity

最後一次觀察"swap詭計", 或者說是,通用的swap.交換兩個容器的內容,包括交換它們的迭代器,指針和引用.在一個容器中
迭代器,指針和引用,在變換後的另一個容器中仍有效並指向同一個元素.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章