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<int(int)> 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: "<<x<<std::endl;

}
int main() {

std::vector<int> 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: "<<x<<std::endl;
}

};
int main() {

std::vector<int> 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<int> arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),[](int x){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<int> 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<int> arr = {1,3,5,7,9};
std::for_each(arr.begin(),arr.end(),={std::cout<<"x: "<<x*times*others<<std::endl;}); // [=]表示全部按值捕获
return 0;

}
4.2 按引用捕获

include

include

include

int main() {

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

}

相关文章
|
2月前
|
存储 C++
C++语言中指针变量int和取值操作ptr详细说明。
总结起来,在 C++ 中正确理解和运用 int 类型地址及其相关取值、设定等操纵至关重要且基础性强:定义 int 类型 pointer 需加星号;初始化 pointer 需配合 & 取址;读写 pointer 执向之处需配合 * 解引用操纵进行。
207 12
|
3月前
|
程序员 编译器 C++
【实战指南】C++ lambda表达式使用总结
Lambda表达式是C++11引入的特性,简洁灵活,可作为匿名函数使用,支持捕获变量,提升代码可读性与开发效率。本文详解其基本用法与捕获机制。
146 45
|
7月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
196 15
|
6月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
216 12
|
7月前
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
132 8
|
11月前
|
算法 编译器 C++
【C++11】lambda表达式
C++11 引入了 Lambda 表达式,这是一种定义匿名函数的方式,极大提升了代码的简洁性和可维护性。本文详细介绍了 Lambda 表达式的语法、捕获机制及应用场景,包括在标准算法、排序和事件回调中的使用,以及高级特性如捕获 `this` 指针和可变 Lambda 表达式。通过这些内容,读者可以全面掌握 Lambda 表达式,提升 C++ 编程技能。
495 3
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
260 5
|
存储 编译器 C语言
深入计算机语言之C++:类与对象(上)
深入计算机语言之C++:类与对象(上)
114 0
|
存储 分布式计算 编译器
深入计算机语言之C++:C到C++的过度-2
深入计算机语言之C++:C到C++的过度-2
|
编译器 Linux C语言
深入计算机语言之C++:C到C++的过度-1
深入计算机语言之C++:C到C++的过度-1
135 0