Effective STL 學習筆記 Item 30: 保證目標區間足夠大

1 容器區間與算法

STL 容器吸引人的地方之一在於它可以自動管理內存,在有新的元素插入時候(經過 push_back(), push_front(), insert() )能夠自動分配空間。但要注意的是,若是新的元素不是經過上述的 navive method 加進來的話,容器不會自動分配內存,例以下面的代碼: css

1: int transmogrify(int x); // this function produces some new value from x.
2: vector<int> values;
3: vector<int> results
4: 
5: transform(values.begin(), values.end(), results.end(), transmogrify);

這裏有兩個問題: html

  • 第五行代碼會直接向 results 的尾部寫入數據,而尾部的內存未知,會引起問題
  • 直接的操做不會改變容器內部記錄的 size & capacity ,從而破壞的容器。

2 back_inserter

咱們應該想辦法調用 push_front,push_back or insert 來插入數據: java

int transmogrify(int x); // this function produces some new value from x.
vector<int> values;
vector<int> results

transform(values.begin(), values.end(), back_inserter(results), transmogrify);

3 front_inserter

若是上面的代碼中使用的是能夠雙向插入數據的容器( deque or list ),還能夠使用 push_frontc++

1: int transmogrify(int x); // this function produces some new value from x.
2: list<int> values;
3: list<int> results
4: 
5: transform(values.begin(), values.end(), front_inserter(results), transmogrify);

上面的代碼還有個問題,因爲每一個數據都會被插到頭部,實際上最後獲得的 results 裏面數據的順序和 values 裏面是相反的,咱們能夠反向遍歷 values: 算法

int transmogrify(int x); // this function produces some new value from x.
list<int> values;
list<int> results

transform(values.rbegin(), values.rend(), front_inserter(results), transmogrify);

4 inserter

front_inserter & back_inserter 能夠向前或者向後插入數據,而 inserter 則能夠向任意位置插入數據: sql

int transmogrify(int x); // this function produces some new value from x.
vector<int> values;
vector<int> results

transform(values.begin(), values.end(),
          inserter(results, results.begin() + results.size()/2),
          transmogrify);

5 inserter & reserve

Item 14 中提到過,vector 插入式數據可能會引發內存的從新分配,從而影響性能,對於前面的幾個例子來講,咱們能夠預先算出插入新的數據後 vector 有多大,所以能夠是全部 Item 14 中提到過的方法來優化: bash

int transmogrify(int x); // this function produces some new value from x.
vector<int> values;
vector<int> results

result.reserve(result.size() + values.size());
transform(values.begin(), values.end(),
          inserter(results, results.begin() + results.size()/2),
          transmogrify);
相關文章
相關標籤/搜索