lambda表达式
lambda表达式在很多语言都是有的,c++当然是有的,但是像C语言就没有这个。和很多语言相同c++的lambda表达式都是为了简化代码,当我们需要传函数的时候我们就可以用lambda表达式写一个匿名函数。
书写格式:
[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略。
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。
这里没加mutable。一般用auto来接收这个函数。
比如我们需要来一个对于自定义类型的排序。我们 不需要再去写对应的仿函数了,直接传一个lambda表达式就行了。
class student
{
string name ;
int score;
public:
student(const string& n , int sc )
{
name = n;
score = sc;
}
int getscore()
{
return score;
}
};
void test2()
{
vector<student> ve={ student("ldaoda",124),student("爱困",123),student("蒙lei" ,100) };
sort(ve.begin(), ve.end(), [](student x, student y)->bool {return x.getscore() > y.getscore(); });
for (auto& e : ve)
{
cout << e.getscore() << " ";
}
}
其实lambda的底层其实跟仿函数类似的。传入的参数就是进行构造。后面的返回值和函数内容就是去实现一个仿函数。
function包装器
function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。功能就是将函数包装起来。
int f(int a, int b)
{
return a + b;
}
struct Functor
{
public:
int operator() (int a, int b)
{
return a + b;
}
};
class Plus
{
public:
static int plusi(int a, int b)
{
return a + b;
}
double plusd(double a, double b)
{
return a + b;
}
};
void test3()
{
// 函数名(函数指针)
std::function<int(int, int)> func1 = f;
cout << func1(1, 2) << endl;
// 函数对象
std::function<int(int, int)> func2 = Functor();
cout << func2(1, 2) << endl;
// lamber表达式
std::function<int(int, int)> func3 = [](const int a, const int b)
{return a + b; };
cout << func3(1, 2) << endl;
// 类的成员函数
std::function<int(int, int)> func4 = &Plus::plusi;
cout << func4(1, 2) << endl;
//因为非静态成员函数需要生成对象才能取。所以需要搞个匿名对象取一个this指针。
std::function<double(Plus, double, double)> func5 = &Plus::plusd;
cout << func5(Plus(), 1.1, 2.2) << endl;
}
bind包装器
std::bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可
调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。一般而
言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M
可以大于N,但这么做没什么意义)参数的新函数。同时,使用std::bind函数还可以实现参数顺
序调整等操作。
给个简单的栗子:
int sub(int x, int y)
{
return x - y;
}
using std::placeholders:: _1;//展开头文件_1表示第一个参数,_2表示第二个参数,以此类推。
using std::placeholders:: _2;
using std::placeholders:: _3;
void test4()
{
auto s = bind(sub, 100, _1);//生成一个新函数,第一x参数传默认值,第二个参数传我们给的值
cout << s(2); //这里对参数的顺序的定义是从第一个没有被占用的值开始计算。
}
这里的auto其实就是替换的function。
绑定成员函数:
class Sub
{
public:
int sub(int a, int b)
{
return a - b;
}
};
void test4()
{
Sub s1;
function<int(int, int)> func1=bind(&Sub::sub,s1,_1,_2);
cout<<func1(1,2);
}