C++ Lambda表达式和函数对象

C++ 的泛型算法

C++ 提供了许多泛型算法, 部分算法可能需要我们提供一个谓词,谓词是一个可调用的表达式,根据算法的不同接受一个或二个参数,分别称为 一元谓词和二元谓词。 既然是可调用的表达式, 则可以是以下的三种:

  1. 一般函数 —— 直接传函数名
  2. Lambda 表达式
  3. 函数对象

Lambda 表达式

lambda 表达式所表示的就是一个可调用的代码单元,可以理解为未命名的内联函数,使用 Lambda 表达式的关键是理解捕获列表。

声明格式: [ 捕获列表 ] ( 参数列表 ) -> 返回值类型 { 函数体 }

捕获列表可用于传递额外的参数,捕获是指函数体所使用到的外部的变量, 有如下类型:

类型 作用
[=] 值捕获,类似 const T
[&] 引用捕获,类似 T &
[this] 所在类成员捕获
[v1, v2, … ] 值捕获指定变量

使用 Lambda 表达式时需要知道, 当函数体仅有一个 return 语句时, 编译器可以推算出返回值类型, 除此之外若要返回,都要显示的声明返回值类型。对应值捕获的变量,是不允许修改变量值的, 若要改变, 则使用 mutable 关键字, 如下例:

int a = 0;
auto func = [a]() mutable -> bool { ++a; return a; }
func(); // 返回 1, 外面的 a 保持为 0 。

函数对象 Function objects

函数对象就是重载了 () 的类, 如下例:

class My_cmp
{
	bool operator()(int a, int b) { return a < b; }
};

函数对象存在的意义就是, 作为一个类他可以拥有自己的状态,这是其他函数都不能比较的(函数内的静态变量不属于对应函数的状态,而且生存周期不恰当)。

除了自己编写函数对象, functional 也提供了一些内置的函数对象, functional 可以分成两个模块:

  1. 函数
    用于包装并返回函数对象。
    C++ Lambda表达式和函数对象_第1张图片
    bind 可以将函数和参数固定绑定, 见下面的例子:
auto func = [](int a,int b){return a < b;};
auto func_binded = bind(func, placeholders::_1, 10); // _1 是占位符, 表示传给 func_binded 的第一个参数在 func 中的位置。
// func_binded 已经变成一元谓词
cout << func_binded(5) << endl; // 输出 1 

  1. 类也可以进一步划分,包装类和操作类(函数对象)

    • 包装类
    • 操作类 —— 都重载了 ()
      逻辑和数学运算C++ Lambda表达式和函数对象_第2张图片

你可能感兴趣的:(学习,C++,c++,Lambda表达式,函数对象,谓词)