泛型算法: 當(dāng)我們希望用戶可以有更多有用的操作(針對容器)的時(shí)候,標(biāo)準(zhǔn)庫并沒有給每個(gè)容器定義自己的成員函數(shù)观谦,而是定義了一組泛型算法浩螺,實(shí)現(xiàn)了(包括)經(jīng)典算法例如排序靴患。
算法依賴于迭代器,所有順序容器都有迭代器接口
泛型算法分為只讀算法要出,寫算法鸳君,定制操作
只讀算法
1、accumulate(vec.begin(),vec.end(),0)? 和的初始值為0
前提患蹂,容器元素可加
2. equal(1.begin(),1.end(),2.begin())
比較相等函數(shù)
只接受一個(gè)單一迭代器來表示第2個(gè)容器的算法或颊,一般來說第2個(gè)容器的長度與第一個(gè)一樣
寫算法
寫算法確保原序列大小不釣魚算法寫入的數(shù)目
1.fill()
2.fill_n(dest, n , val)
當(dāng)vec 是空vector 時(shí), 上面的fill_n 算法有寫入的風(fēng)險(xiǎn)传于。
這時(shí)引入back_inserter 插入迭代器囱挑, 將普通迭代器轉(zhuǎn)換成插入迭代器, 當(dāng)我們通過插入迭代器時(shí)沼溜,一個(gè)與賦值號右側(cè)相等的元素被添加到元素處(PS 不是直接被賦值進(jìn)去)
vector <int > vec ;
fill_n(back_inserter(vec, 10 , 0)
3.copy( source.begin(), source.end(), dest.begin())
dest 容器大小必須與source 大小至少一樣大才可以
4. sort( source.begin(). source.end())
利用元素的? < 運(yùn)算符 升序排序
5. unique( )
使得容器的重復(fù)元素放在尾部平挑,返回迭代器指向最后一個(gè)不重復(fù)元素的元素
6.source.earse()
刪除和添加元素的話,泛型算法是不對容器操作系草,僅對迭代器通熄,所以要直接調(diào)用容器自身的操作
定制操作
引入目的:
很多算法都需要比較輸入的元素。 這時(shí)候標(biāo)準(zhǔn)課算法提供了額外的定義悄但,允許我們使用自定義的算法
for example:
bool isShorter(const string & s1, const string & s2)
{
return? s1.size() < s2.size();
}
caller: sort(source.begin(),source.end(),isShorter);
stable_sort () : 用途 ---? 保證相等元素間的相對順序
函數(shù)調(diào)用符重載:
struct A
{
? ? int operator()(int val )
????{
? ? ?? return val < 0 ? -val : val;
? ? }
}
可以使得類對象一樣使用實(shí)參列表棠隐,調(diào)用函數(shù)般石抡,成為函數(shù)對象類檐嚣,而且一般含有狀態(tài)
e.g?
class PrintString
{
public:?
? ? ? ? PringString(ostream & os, char c = ' '): o(os),sep(c){}
????????void operator()(const string & c ) { o<< c << sep;}
pprivate:
? ? ? ? ostream os;
? ? ? ? char sep;
}
這樣的話,
for_each(source.begin(),source.end(), PrintString(cerr,'\n')) // 必須生成為對象才可以被調(diào)用
調(diào)用for_each 時(shí)啰扛, 會(huì)把每個(gè)元素注入到函數(shù)對象類的是璀璨列表中嚎京,打印到cerr 并且以換行符分割。
特別的 lambda 也是一個(gè)函數(shù)對象類
生成的函數(shù)對象類有兩種情況:
A. 當(dāng)捕獲列表中的參數(shù)是引用隐解,則不需為lambda 產(chǎn)生的類存儲(chǔ)為數(shù)據(jù)成員
B.當(dāng)捕獲列表中的參數(shù)是值引用鞍帝,則產(chǎn)生的類必須為每個(gè)捕獲的變量建立對應(yīng)的數(shù)據(jù)成員,同時(shí)構(gòu)建函數(shù)煞茫。
for instance:
auto wc = find_if(words.begin(). words.end().[sz](const string & s1, const string & s2) {return s1.size() < s2.size(};});
class SizeComp
{
? ? SizeComp(size_t n): sz(n) {}
????bool operator()(const string &s)const {return s.size(( < sz;}
}
lambda 產(chǎn)生的函數(shù)對象類并不含默認(rèn)構(gòu)造函數(shù)帕涌,賦值運(yùn)算符和默認(rèn)析構(gòu)函數(shù)。
可變lambda
當(dāng)捕獲列表中是值拷貝回來的參數(shù)续徽,若希望改變該參數(shù)時(shí)蚓曼,則在 函數(shù)體前加mutable
f = [v1] mutable{return ++ v1;}
參數(shù)綁定
出現(xiàn)目的:
當(dāng)在代碼中出現(xiàn)很多相同的操作時(shí),應(yīng)該定義一個(gè)函數(shù)钦扭,但是定義的函數(shù)中并不能直接捕獲函數(shù)上下文中使用的參數(shù)
用bind 函數(shù)可以解決向 函數(shù)傳遞一個(gè)參數(shù)的情況
例子:
auto check6 = bind(check_size, _1, 6)
_1 代表 check6 中的參數(shù)對應(yīng)check_size 的第一個(gè)參數(shù)
只有一個(gè)占位符說明check6 接受一個(gè)參數(shù)
修改后:
auto wc =? find_if (source.begin(),source.end(),bind(check_size, _1 , 6)
PS: _1 使用的話要聲明其命名空間纫版。 _1 -> using std::placeholder::_1
順序容器push_back 和push_front 區(qū)別:
1. 是否可以常數(shù)操作
push_back : 除 array 和forward_list 外都可以
push_front : list deque.forward_list 均可以
順序容器insert 方法可以對任何容器操作。只不過對特定容器會(huì)耗時(shí)