1. 程式人生 > >effective STL

effective STL

back bsp 比較 base erro int 結構 remove 執行

1.標準序列容器 vector/deque/list/string

2.標準關聯容器 set/map/multise/multimap

3.

連續內存容器(contiguous-memory container) string/vector/deque

基於節點容器(node-based container) list/set/map/multiset/multimap/hash_set/hash_map/hash_multiset/hash_multimap

4.叠代器

input iterator(istream_iterator)

output iterator(ostream_iterator)

forward iterator

bidirectional iterator

random access iterator

5.從屬類型

typename

6.排序效率

partition> stable_partition? nth_element? partial_sort> sort> stable_sort

7.比較sort與qsort

sort默認比較方式為函數對象(判別式(純函數))而qsort則是函數指針,區別在於sort函數對象是內聯,在編譯時用代碼替換,

而函數指針則需要在調用時先保存狀態然後調用函數.

8.純函數

參數相同時不管何時調用都返回相同結果(bool operator()(T valA,T valB)const

加入const時,函數內變量默認const類型

bool operator()(int key) const
{
  //std::set<int> data
  std::set<int>::iterator it= data.find(key); //error
}

9.remove

std::vector<int> data;
.
.
data.erase(std::remove(data.begin(),data.end(),val),data.end());

remove復雜度 std::distance(container.begin(),container.end())

erasef復雜度 線性(析構函數/刪除變量),賦值運算操作刪除變量後剩下element數量

10.容器成員函數與algorithm同名算法

成員函數通常比同名算法更快且結合更加緊密.標準關聯容器(set/map)的find與algorithm find的釋放方式不同,

成員函數find依據容器的實現(通常是紅黑樹)復雜度 log size(),而find線性查找.且STL算法以相等性判斷兩個對象

是否具有相同值而關聯容器則使用等價性進行他們的相同性測試 !(a< b) && !(b< a)

list成員函數比同名algorithm算法性能更好,維護指針比拷貝對象開銷小得多.list.sort()與sort(),sort要求參數為隨機

叠代器而list只具有雙向叠代器.

11.多線程環境中使用引用計數string

由避免內存分配和字符拷貝所節省下來的時間比不上花在背後同步控制上的時間

12.istreambuf_iterator

std::ifstream input_file("**.txt");
input_file.unsetf(std::ios::shipws);
std::string file_data((std::istream_iterator<char>(input_file)),std::istream_iterator<char>());

istream_iterator內部使用operator>>函數實際上執行格式化的輸入,這意味著你每次調用operator>>操作符,它都要執行

許多附加操作:一個內部的sentry對象的構造和析構(sentry是調用operator>>的過程中進行設置和清理行為的特殊iostream對象);

檢查那些可能會影響其行為的流標誌(如skipws);檢查所有可能發送的讀取錯誤;如果遇到錯誤,還需要檢查輸入流的異常屏蔽標誌以

決定是否拋出響應異常.istreambuf_iterator<char>直接從流的緩沖區讀取下一個字符(istreambuf_iterator<char>對象從一個輸入流

istream s中讀取下一個字符的操作通過s.rdbuf()->sgetc()來完成),不會跳過任何字符.

13.函數指針是按值傳遞

STL函數對象是函數指針的一種抽象和建模形式

14.要求排序區間的STL算法

binary_search  lower_bound  upper_bound  equal_range  merge  inplace_merge  includes

set_union  set_intersection  set_difference  set_symmertric_difference

(unique/unique_copy)不要求排序區間但是它的現實是消除相鄰相等element

std::vector<int,std::greater<int>> data;
.
.
auto it= std::find(data.begin(),data.end());//默認std::less<int>

在使用STL算法是所采取的比較函數對象必須與容器排序所采取比較函數對象相同.

equal_range 比lower_bound開銷更大,但lower_bound返回後還需要手工檢測所返回是否是需要element,序列容器默認是相等性,

而關聯容器是等價性如果是關聯容器返回則需要 if(it!= container.end() && !(*it< val))

set/map檢測element是否存在使用count

multiset/multimap 檢測element是否存在使用find,find並非一定是第一個具有此值elemnt(使用lower_bound可以達到此功能,但

需要手動檢測等價性)

15.inserter/back_inserter/front_inserter

inserter返回inserter_iterator對象,此對象包含一個iter記錄下一次插入的位置,在operator*運算函數中調用源對象的inserter函數並記錄返回iterator.

back_inserter返回back_inserter_iterator對象,在operator*運算函數中調用源對象back_inserter

front_inserter返回front_inseter_iterator對象,在operator*運算函數中調用源對象front_inserter

16.關聯容器比較函數在等值時返回false(等價性)

std::set<int,std::less_equal<int>> data;
data.insert(10);
data.insert(10); //成功,但破壞了容器內部數據結構

std::multiset<int,std::less_equal<int>> multi_data;
mutil_data.insert(10);
mutil_data.insert(10);
auto it= mutil_data.equal_range(10); //!(10<= 10) && !(10<= 10)
if (it.first== it.second)
{
  std::cout<<"error\n";   
}

effective STL