C++语言的lambda表达式

简介: C++从函数对象到lambda表达式以及操作参数化

函数对象(function object)是指一个类重载函数运算符"()"后,使用类变量调用函数运算符时,其行为类似函数调用,所以也称为仿函数(functor)。

lambda表达式是函数对象的语法糖,使用三种括号来定义:

{};
[]内可以是空白,表示不捕获任何lambda表达式外部的任何变量,其内也可以声明需要捕获的lambda表达式外部的变量,可以是值捕获,也可以是引用捕获。

()内用于定义lambda表达式的参数;

{}内用于定义语句体,相当于函数的函数体。

lambda表达式直接调用的语法形式:

{}(); // 第二对小括号()表达式表示调用,内部的值对应第一对小括号()内声明的参数。
操作参数化是指用函数指针、函数对象或lambda表达式做函数参数。

lambda表达式这种语法形式的引入主要用于操作参数化。

1 成员函数与函数对象
成员函数:

include

class AddNum{
public:
AddNum(int num):num(num){}
int addNum(int x)const{
return num
+x;
}
private:
int num_;
};

int main() {
auto add_num = AddNum(10);
auto x = add_num.addNum(5);
std::cout<<"x:"<<x<<std::endl;
return 0;
}
将成员函数改写为函数对象的形式:

include

class AddNum{
public:
AddNum(int num):num(num){}
int operator()(int x)const{
return num
+x;
}
private:
int num_;
};

int main() {
auto add_num = AddNum(10);
auto x = add_num(5);
std::cout<<"x:"<<x<<std::endl;
return 0;
}
2 从函数对象到lambda表达式
lambda表达式:

include

int main() {
auto x = num=10{return num + x;}(5);
std::cout<<"x:"<<x<<std::endl;
return 0;
}
lambda表达式是函数对象的语法糖。

也可以对lambda表达式进行命名,命名后可以如同函数一样调用:
//代码效果参考:http://www.zidongmutanji.com/bxxx/162556.html

include

int main() {
auto add_num = num=10{return num + x;};
auto x = add_num(5);
std::cout<<"x:"<<x<<std::endl;
return 0;
}
auto推导的lambda表达式类型相当于以下类型:

include

include

int main() {
std::function add_num = num=10{return num + x;};
auto x = add_num(5);
std::cout<<"x:"<<x<<std::endl;
return 0;
}
3 操作参数化
操作参数化也就是用函数指针、函数对象或lambda表达式做函数参数。

如for_each()函数:

template
Function for_each(InputIterator first, InputIterator last, Function fn)
{
while(first!=last) {
fn (*first); // fn是for_each的参数,first也是,同时也是fn的参数
++first;
}
return fn; // or, since C++11: return move(fn);
}
3.1 使用函数指针让操作参数化

include

include

include

void print_int(int x){
std::cout<<"x: "< arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),print_int);
return 0;
}
3.2 使用函数对象让操作参数化

include

include

include

struct print_int{
void operator()(int x){
std::cout<<"x: "< arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),print_int());
return 0;
}
3.3 使用lambda表达式让操作参数化

include

include

include

int main() {
std::vector arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),{std::cout<<"x: "<<x<<std::endl;});
return 0;
}
4 lambda表达式还可以捕获表达式外部的变量
4.1 按值捕获

include

include

include

int main() {
int times = 2;
int others = 3;
std::vector arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),times{std::cout<<"x: "<<x*times<<std::endl;}); // 按值捕获times
return 0;
}
也可以全部按值捕获:

include

include

include

//代码效果参考:http://www.zidongmutanji.com/bxxx/484144.html

int main() {
int times = 2;
int others = 3;
std::vector arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),={std::cout<<"x: "<<xtimesothers<<std::endl;}); // [=]表示全部按值捕获
return 0;
}
4.2 按引用捕获

include

include

include

int main() {
int times = 2;
int others = 3;
std::vector arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),×{std::cout<<"x: "<<x*++times<<std::endl;}); // [×]表示按引用捕获times
return 0;
}
也可以全部按引用捕获:

include

include

include

//代码效果参考:http://www.zidongmutanji.com/bxxx/472460.html

int main() {
int times = 2;
int others = 3;
std::vector arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),&{std::cout<<"x: "<<x++times++others<<std::endl;}); // [&]表示全部引用
return 0;
}

相关文章
|
6天前
|
算法 编译器 C++
C++一分钟之—Lambda表达式初探
【6月更文挑战第22天】C++的Lambda表达式是匿名函数的快捷方式,增强函数式编程能力。基本语法:`[capture](params) -&gt; ret_type { body }`。例如,简单的加法lambda:`[](int a, int b) { return a + b; }`。Lambda可用于捕获外部变量(值/引用),作为函数参数,如在`std::sort`中定制比较。注意点包括正确使用捕获列表、`mutable`关键字和返回类型推导。通过实践和理解这些概念,可以写出更简洁高效的C++代码。
29 13
|
4天前
|
存储 Java C#
C++语言模板类对原生指针的封装与模拟
C++|智能指针的智能性和指针性:模板类对原生指针的封装与模拟
|
5天前
|
数据安全/隐私保护 C++
C++语言深入理解类的封装与数据隐藏
深入理解类的封装与数据隐藏
|
10天前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
18 3
|
4天前
|
存储 编译器 开发工具
C++语言教程分享
C++语言教程分享
|
4天前
|
自然语言处理 编译器 C语言
C++语言入门教程
C++语言入门教程
|
4天前
|
存储 编译器 程序员
C++语言基础学习
C++语言基础学习
|
4天前
|
存储 编译器 程序员
C++语言速成方法
C++语言速成方法
|
4天前
|
存储 编译器 C++
|
15天前
|
程序员 C语言 C++
【C++语言】继承:类特性的扩展,重要的类复用!
【C++语言】继承:类特性的扩展,重要的类复用!