这个应该在使用中学习,这里只会记录一些注意事项。
- 算法不会检查写操作的合法性
使用C++中的lambda表达式
谓词
谓词是一个可以调用的表达式,返回结果是一个能用于条件的值。标准库算法使用的谓词分为一元谓词(接受单一参数,fill)和二元谓词(拥有两个参数,sort)
lambda表达式
lambda表达式可以看作未命名的内联函数。它具有以下形式
[capture list] (parameter list) -> return type
{
function body
}
- lambda必须使用尾置返回类型
- 可以会略返回类型和参数列表,但必须具有捕获列表和函数体
- lambda不能形参不能具有默认值。
lambda的捕获和返回类型
分为值捕获和引用捕获
[]不捕获
[name]值捕获
[&name]引用捕获
[=]隐式值捕获
[&]隐式引用捕获
[=,name],除了被标出来的按引用捕获,其他按值
[&,name],同上
当lambda表达式只有一条简单的return语句时,编译器可以推断出返回类型,此时可以省略返回类型。
然而更复杂的多条return语句时,就必须指定返回类型。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>G{11,22,33,41,53,634,75};
vector<int>H(G);
bool cmp(const int& a, const int& b)
{
return a % 10 < b % 10;
}
int main()
{
sort(begin(G), end(G),
[](const int& a, const int& b)->int {return a % 10 < b % 10; });
//传递lambda表达式
sort(begin(H), end(H), cmp);
//传递函数
for (int i = 0; i <= 6; ++i)
{
cout << G[i] << " " << H[i] << endl;
}
return 0;
}
标准库bind函数(头文件functional)
lambda表达式适用于较小的的函数,当我们需要编译较大的函数,并多次使用它,就必须定义一个函数,并且传递函数参数。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int>G{ 1,2,3,4,6,7,8 };
int limit = 4;
for_each(G.begin(), G.end(),
[limit](const int& a)->void {if (a > limit)cout << a << endl; });
return 0;
}
如果传递函数,因为limit是局部变量,而且for_each是需要一元谓词。所以函数形参只能有一个,那么这个时候就要用到bind函数。
调用bind的一般形式为
auto newcallable = bind(callable,arg_list);
arg_list包含_1,_2,…_n之类的名字,这些参数是占位符,占据传递给call的参数位置,_n表示newcall第n个参数位置。使用占位符需要包含std::palceholder的命名空间。
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
void judge(const int& a, int lim)
{
if (a > lim)
cout << a << endl;
}
int main()
{
using namespace std::placeholders;
vector<int>G{ 1,2,3,4,6,7,8 };
int limit = 4;
auto jd = bind(judge, _1,limit);
for_each(G.begin(), G.end(), jd);
for_each(G.begin(), G.end(), bind(judge, _1, limit));
//上述等价的
return 0;
}
- bind函数都是默认值传递,如果需要引用传递,要使用ref函数
#include<iostream>
#include<algorithm>
#include<vector>
#include<functional>
using namespace std;
ostream& judge(ostream& os, const int &a, int lim)
{
if (a > lim)
return os << a << endl;
else return os;
}
int main()
{
using namespace std::placeholders;
int lim = 6;
vector<int>G{ 1,2,3,5,6,7,8,89 };
//auto jd = bind(judge, ref(cout), _1, lim);
for_each(G.begin(), G.end(), bind(judge, ref(cout),_1, lim));
//cout 是流对象,不允许拷贝,使用ref传引用。
return 0;
}