🐶博主主页:@ᰔᩚ. 一怀明月ꦿ
❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++
🔥座右铭:“不要等到什么都没有了,才下定决心去做”
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
c++11中的lambda表达式
lambda表达式的基本格式
[capture list] (parameters) -> return_type {// 函数体 }
* capture-list:用于捕获外部变量,可以省略。捕获方式有三种:
* [&]:以引用方式捕获所有外部变量。
* [=]:以值的方式捕获所有外部变量。
* [var1, var2, ...]:指定需要捕获的外部变量列表,可以使用 & 或 = 来指定捕获方式。
* parameter-list:函数参数列表,类似于普通函数的参数列表,可以省略。
* return-type:返回类型,可以省略,编译器可以自动推断。
* body:Lambda 函数体,类似于普通函数体,包含了执行的语句。
下面是一个简单的示例,展示了如何在 C++11 中使用 Lambda 表达式:
不使用捕捉列表 capture-list
#include <iostream>int main() {// Lambda 表达式示例:计算两个数的和//参数列表有两个整数auto add = [](int a, int b) -> int {return a + b;};// 调用 Lambda 表达式int result = add(3, 4);std::cout << "Result of add function: " << result << std::endl;// Lambda 表达式示例:打印 Hello World//参数列表为空auto printHello = []() {std::cout << "Hello, World!" << std::endl;};// 调用 Lambda 表达式printHello();return 0; }
使用捕捉列表 capture-list
int main() {int x=119,y=120;cout<<"x="<<x<<":"<<"y="<<y<<endl;//参数列表为空,调用时不需要传递参数auto f1=[&x,&y](){int temp;temp=x;x=y;y=temp;};//[]就是捕捉列表,可以捕捉lambda表达式所在函数(这里是main函数)里的变量,提供自己使用,这里采用的是引用捕捉x,y,因为我们要在lambda的函数体里修改x,y,如果不需要修改x,y的值时,可以采用值捕捉[x,y](){}f1();cout<<"x="<<x<<":"<<"y="<<y<<endl;return 0; }
使用捕捉列表 capture-list的其他用法
int main() {int x = 1,y = 2,z = 3;//以值的方式捕捉所有的变量auto f1=[=](){cout<<x<<y<<z<<endl;};//[=]是捕捉所有变量的意思f1();//以引用的方式捕捉所有的变量auto f2=[&](){cout<<x<<y<<z<<endl;};//[&]是捕捉所有变量的意思f2();//以值的方式捕捉所有的变量,指定x,y以引用捕捉auto f3=[=,&x,&y](){cout<<x<<y<<z<<endl;};f3();return 0; }
lambda的底层其实是一个仿函数
包装器
function
function
是 C++ 标准库中的一个模板类,用于封装可调用对象,包括函数指针、函数对象、lambda 表达式等等,使用时需要functional头文件。
function
的定义如下:template<class R, class... Args> class function<R(Args...)>;
其中
R
是返回类型,Args
是参数类型。通过这个定义,你可以创建一个function
对象,它可以接受参数为Args
类型,返回类型为R
类型的可调用对象。事例1)
void swap_func(int& r1,int& r2) {int temp;temp=r1;r1=r2;r2=temp; }struct swap_2 {void operator()(int& r1,int& r2){int temp;temp=r1;r1=r2;r2=temp;} }; int main() {int x=119;int y=120;auto lambdaswap=[](int& r1,int& r2){int temp;temp=r1;r1=r2;r2=temp;};//包装器指向swap_func函数function<void(int&,int&)> f1=swap_func;f1(x,y);cout<<"x:"<<x<<" y:"<<y<<endl;//包装器指向仿函数function<void(int&,int&)> f2=swap_2();//swap_2() 是一个函数调用操作符 operator() 被重载的类 swap_2 的匿名对象。在 C++ 中,类的对象也可以被当作函数使用,如果该类定义了一个函数调用操作符 operator(),就可以像调用函数一样使用这个对象。在这种情况下,swap_2() 返回的匿名对象会被当作函数使用,具体来说,它会被当作一个函数对象使用。f2(x,y);cout<<"x:"<<x<<" y:"<<y<<endl;//包装器指向lambda表达式function<void(int&,int&)> f3=lambdaswap;f3(x,y);cout<<"x:"<<x<<" y:"<<y<<endl;return 0; }
事例2)
class Test { public:int add(int x,int y){return x+y;}static int add_s(int x,int y){return x+y;} }; int main() {//包装器指向静态成员函数//需要加域名function<int(int,int)> f1=Test::add_s;int sum=f1(1,2);cout<<sum<<endl;//包装器指向普通成员函数//1.需要加域名//2.需要取地址//3.function需要多加一个类的指针(因为成员函数的参数列表中,隐含一个this指针)function<int(Test*,int,int)> f2=&Test::add;Test t1;int num=f2(&t1,1,2);cout<<num<<endl; }
function封装可调用对象,包括函数指针、函数对象、lambda 表达式时,一定保证参数类型是相同的
bind
在C++中,
std::bind
是一个函数模板,用于创建一个可调用对象,该对象可以绑定到函数、成员函数、函数对象或者其他可调用对象,并且可以指定部分或全部参数的值。std::bind
允许你在调用时提供缺少的参数,或者在调用时提供额外的参数。
bind
的基本语法如下:template< class F, class... Args > /*unspecified*/ bind( F&& f, Args&&... args );
其中
F
是可调用对象的类型,args
是可调用对象的参数。bind
返回一个可调用对象,该对象可以通过调用其operator()
来调用绑定的函数或函数对象,并传递给它们参数。事例
class Test { public:int add(int x,int y){return x+y;}static int add_s(int x,int y){return x+y;} };int sub(int x,int y) {return x-y; }int main() {//调整参数顺序function<int(int,int)> f1=bind(sub,placeholders::_2,placeholders::_1);//bind第一个参数是函数名,placeholders::_2,placeholders::_1可用来改变参入参数的顺序的int num=f1(2,0);//顺序变为sub(0,2)cout<<num<<endl;//调整参数个数function<int(int)> f2=bind(sub,100,placeholders::_1);//我们也可以在绑定的时候,提前加入指定的参数,例如这里的100,这样我们调用sub时就只需要传一个参数int num1=f2(1);cout<<num1<<endl;//调整参数个数function<int(int,int)>f3=bind(&Test::add,Test(),placeholders::_1,placeholders::_2);//绑定的Test是一个自定义类型的普通成员函数,传函数名时需要加域名和&,这个Test()是Test的匿名对象,需要传递给this指针int num2=f3(2,3);cout<<num2<<endl;return 0; }
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸