只讀算法
(1)accumulate返回容器的和
int sum = accumulate(vec.cbegin(),vec.cend(),0);
string sum = accumulate(v.cbegin(),v.cend(),string(""));//注意第三個參數不接受"",因爲const char*類型沒有重載“+”會編譯錯誤
(2)equal比較兩個等長的容器(元素個數相同)是否保存相同的值
equal(vec1.cbegin(),vec1.cend(),vec2.cbegin());
寫容器元素算法
(1)fill填充元素值
fill(vec.begin(),vec.end(),0);
(2)back_inserter接收一個容器的引用,返回該容器的插入迭代器,可以做插入容器操作
vector<int> vec;
auto it = back_inserter(vec);
*it = 42; //vec中有42
vector<int> vec;
fill_n(back_inserter(vec),10,0); //添加10個元素到vec
(2)copy複製數組
int a1[] = {0,1,2,3,4,5,6};
int a2[sizeof(a1)/sizeof(*a1)];
auto ret = copy(begin(a1),end(a1),a2);
(3)replace將容器內指定值置換成另一個值
replace(vec.begin(),vec.end(),0,42); //0換成42;
(4)replace_copy如果不想改變原數組可以使用這個,得到置換後的新數組
vector<int> newvec;
replace_copy(vec.begin(),vec.end(),back_inserter(newvec).0,42);
消除重複單詞算法
void elimDups(vector<string>& words)
{
sort(words.begin(),words.end());
auto end_unique = unique(words.begin(),words.end());
words.erase(end_unique,words.end());
}
lambda表達式
(1)標準寫法
[capture list](parameter list) -> return type { function body}
我們可以忽略參數列表和返回類型,但是永遠包含捕獲列表和函數體
vector<int> vec;
sort(words.begin(),words.end(),[](const string& a,const string& b){return a.size()<b.size();}}
(2)捕獲列表
捕獲列表中的參數捕獲該函數所在的局部變量,然後在lambda表達式中可以直接進行使用,而參數列表是外部調用的時候傳入的參數。
//獲取一個迭代器,指向第一個滿足size()>=sz的元素
auto wc = find_if(words.begin(),words.end(),[sz](const string& a){return a.size() >= sz}};
//打印長度大於等於給定值的單詞,每個單詞後面接一個空格
for_each(wc,words.end(),[&os](const string& s){cout<<s<<"";});
(3)隱式捕獲和顯示捕獲
當我們混合喜歡使用隱式捕獲和顯示捕獲時,顯示捕獲的變量必須使用與隱式捕獲不同的方式。即,如果隱式捕獲是引用方式,則顯示捕獲命名變量必須採用值方式,因此不能在其名字前使用&。類似的,如果隱式捕獲採用的是值方式,則顯示捕獲命名變量必須。
(4)可變mutable
默認情況下,對應一個值被拷貝的變量,lambda不會改變其值。如果我們希望能改變一個被捕獲的變量的值,就必須在參數列表首加上關鍵字mutable。因此,可變lambda能省略參數列表:
void fcn3()
{
size_t v1 = 42;
auto f = [v1]()mutable{ return ++v1};
v1 = 0;
auto j = f(); //j = 43;
}
(5)指定lambda返回類型
首先給出一個例子,使用transform算法對容器內所有元素取絕對值
transform(vec.begin(),vec.end(),vec.begin(),[](int i){return i<0 ? -i : i;});
如果修改成如下格式
transform(vec.begin(),vec.end(),vec.begin(),[](int i){if(i<0) return -i else return i;});
發現編譯器過不去。是因爲,默認情況下,如果一個lambda體包含return之外的任何語句,則編譯器假定此lambda返回void,所以我們要指定返回類型
transform(vec.begin(),vec.end(),vec.begin(),[](int i)->int{if(i<0) return -i else return i;});
(6)bind函數
使用bind函數可以解決函數參數不對應的問題,下面是使用bind重排參數順序的實例
using namespace std::placeholders;
sort(vec.begin(),vec.end(),cmp);
sort(vec.begin(),vec.end(),bind(cmp,_2,_1)); //顛倒參數傳遞
使用引用傳遞bind
for_each(vec.begin(),vec.end(),bind(print,ref(os),_1,' '));