在綁定參數這一節,C++11有了新的特性,由於舊版本的綁定參數的語言特性限制更多,也更復雜,所以標準庫定義了兩個分別名爲bind1st和bind2nd的函數,類似bind,這兩個函數接受一個函數作爲參數,生成一個新的可調用對象,該對象調用給定函數,並將綁定的參數傳遞給他。但是這些函數分別只能綁定第一個或第二個參數。
由於這些函數侷限太強,在新標準中已被棄用(deprecated).所謂被起用的特性就是在新版本中不在支持的特性。新的bind應該使用bind。
#include<iostream>
#include <vector>
#include <algorithm>
#include<numeric>
#include<fstream>
#include<functional>
#include<string>
#include<ostream>
using namespace std;
using namespace std::placeholders;
inline void output_date(const vector<string>&s)
{
for (auto i = s.begin(); i != s.end(); i++)
{
cout << *i << " ";
}
cout << endl;
}
bool check_size(const string &s, string::size_type sz)
{
return s.size() > sz;
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
output_date(words);
auto bc = count_if(words.begin(), words.end(), bind(check_size, _1, sz));
}
int main(int argc, char **argv)
{
ifstream in(argv[1]);
if (!in)
{
cerr << "can't open the file";
exit(1);
}
vector<string>words;
string word;
while (in >> word)
words.push_back(word);
biggies(words, 6);
}
用函數替代lambda的方法
這個表示函數代替lambda的方法,其實也就是兩者的區別。當lambda不捕獲局部變量時,用函數替代它是很容易的,但是當lambda捕獲局部變量時就不是那麼簡單了,因爲在這種情況下,算法要求可調用的對象接受的參數個數少於函數所需的參數個數,lambda通過捕獲的局部變量來彌補這個差距,而普通函數是做不到這些的。還好標準庫提供了bind函數。
對於bind()接受幾個參數而言?
由於bind是可變參數的,它接受的第一個參數是一個可調用的函數對象,即實際工作函數A,返回供算法使用的新的可調用對象B。若A接受X個參數,則bind的參數個數應該是X+1,就是除了A外,其他參數應該一一對應A所接受的參數。這些參數中有一部分來在於B(_n),另外一些來自於所處函數的局部變量。
關於lambda表達式
主要代碼如下
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<string>
#include<fstream>
#include <functional>
using namespace std;
using namespace std::placeholders;
void output_date(const vector<string>&s)
{
for (auto i = s.begin(); i != s.end(); i++)
{
cout << *i << " ";
}
cout << endl;
}
void output_date(const vector<int>&s)
{
for (auto i = s.begin(); i != s.end(); i++)
{
cout << *i << " ";
}
cout << endl;
}
void output_date(const vector<string>::iterator beg,const vector<string>::iterator iter)
{
for (auto i = beg; i != iter; i++)
{
cout << *i << " ";
}
cout << endl;
}
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
bool isEnoughLEngth(const string &s1)
{
return s1.size() > 5;
}
/////////////////////////////lambda表達式函數///////////////
void add(int az)
{
auto sumint = [az](int b) { return az + b; };
cout << sumint(1)<<" ";
}
void biggies(vector<string>&words, vector<string>::size_type sz)
{
stable_sort(words.begin(),words.end(),
[sz](const string &s1, const string &s2) { return s1.size() < s2.size(); });
for_each(words.begin(), words.end(), [](const string &s) { cout << s << endl; });
}
void bigge(vector<string> &words, vector<string>::size_type sz,ostream &os=cout,char c=' ')
{
//os隱式捕獲採用引用捕獲方式。c顯式捕獲,值捕獲方式
for_each(words.begin(), words.end(),
[&, c](const string &s) { os << s << c; });
for_each(words.begin(), words.end(),
[=, &os](const string &s) { os << s << c; });
}
ostream &print(ostream&os, const string &s, char c)
{
return os << s << c;
}
int main(int argc, char**argv)
{
vector<string >vec{ "china", "chinese", "word", "hello", "dear", "marry", "hurt" };
stable_sort(vec.begin(), vec.end(), isShorter);//按照字典序排列,首先用長度大小排列,當長度相等則使用字典序。
output_date(vec);
auto iter = partition(vec.begin(), vec.end(), isEnoughLEngth);
output_date(vec.begin(), iter);
auto countnum = count_if(vec.begin(), vec.end(),
[](const string &s) { return s.size() > 5; });
cout <<"vec中有"<< countnum <<"個超過5的單詞"<< endl;
stable_sort(vec.begin(), vec.end(),
[](const string &s1, const string&s2)
{return s1.size() > 5;});//典型的lanbda閉包表達式關係,內置的函數體
auto sum = [](int a, int b) { return a + b; };
cout << sum(6, 5) << endl;;
add(6);
//當以引用捕獲一個lambda變量時,必須保證在閉包執行時變量是存在的
vector<int>veint{ 1, -2, 3, 67, 32, -6, -32, -32, 6, -3, -523, -45, -5334, -3531, 632, 45, 32, 634, 6, 23, 523 };
transform(veint.begin(), veint.end(), veint.begin(),
[](int i)->int { if (i < 0) return -i; else return i; });
//書上說在這裏必須要有尾置返回類型、但是測試時不需要尾置返回類型也可以編譯通過,應該是優化後的結果吧
output_date(veint);
//auto wc = find_if(vec.begin(),vec.end(),bind(_1,add));
system("pause");
}
對於lambda表達式,在函數引用上還是相當方便的,這是C++11的新特性。