C++11Lanbda表达式(匿名函数)

简介: C++11Lanbda表达式(匿名函数)

介绍Lambad表达式

C++11中引入了Lambda表达式 用于定义并创建匿名函数对象,以简化编程工作。

首先我们了解一下Lambda表达式的格式:


[函数对象参数](操作符重载函数参数)mutable->返回值类型{函数体}

1. [capture](parameters)mutable->return-type
2. {
3.     statement;
4. }

1.函数对象参数(也叫捕获列表):[]标识一个Lambda的开始,不可省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些定义Lambda为止时且在Lambda所在作用范围内可见的局部变量和所在类的this。函数对象参数有下面几种:

1.[] 空的,就是无法访问作用域外的。

  1. [=] 等号运算符。表示函数体内可以使用Lambda所在作用范围内且所有可见的局部变量和所在类的this,而且是值传递方式
  2. [&] 取地址运算符。表示函数体内可以使用Lambda所在作用范围内且所有可见的局部变量和所在类的this,而且是引用传递方式
  3. this。函数体内可以使用Lambda所在类中的成员变量。
  4. a。将a按值进行传递。按值传递时,函数体内不能修改传递进来变量的值,因为默认情况下函数是const的。要修改传递进来的值,需要添加mutable关键字。
  5. &a。将a按照引用传递。


2.操作符重载函数参数:表示重载的()操作符的参数,没有参数时,这部分可以省略。参数可以按值和按引用俩种方式进行传参。

3.可修改标识符:mutable声明,这部分可以省略。按值传递时,加上mutable修饰符后就可以修改传进来的拷贝变量。

4.函数返回值:->返回值类型。表示函数返回值类型,当返回值为void,或者函数体中只有一处return的地址时,这部分可以省略。因为只有一处return时编译器可以自动推测出返回值类型。

5.函数体:{} 函数实现的位置。这部分不可省略。当函数体可以为空。


用例说明

值传递

最后加个()就是函数调用。不加的话只是个函数声明。

int main()
{
  // 最后加个()就是函数调用
  [=](int i)
  {
    cout << "LinXi" << i << endl;
  }(3);
  return 0;
}


int main()
{
  // 最后加个()就是函数调用
  int x = 23;
  [x]()
  {
    cout << "LinXi" << x << endl;
  }();
  cout << x << endl;
  return 0;
}

当我尝试修改值传递进去的值时就会报错。

 

引用传递(可读可写)

函数里面修改,外部的x值就会改变。

int main()
{
  // 最后加个()就是函数调用
  int x = 23;
  [&](int& i)
  {
    cout << "LinXi" << ++i << endl;
  }(x);
  cout << x << endl;
  return 0;
}


int main()
{
  // 最后加个()就是函数调用
  int x = 23;
  [&x]()
  {
    cout << "LinXi" << ++x << endl;
  }();
  cout << x << endl;
  return 0;
}

运行结果图:

mutable关键字

int main()
{
  // 最后加个()就是函数调用
  int x = 23;
  [x]()mutable
  {
    cout << "LinXi" << ++x << endl;
  }();
  cout << x << endl;
  return 0;
}


可以看到在函数内部对x的值进行了修改 ,但是外面x的值依然没变。

有返回值

int main()
{
  // 最后加个()就是函数调用
  const int ret = []()->int { return 1024; }();
  cout << ret << endl;
  return 0;
}

实战小例子

使用lambda表达式遍历数据

template<class T, class T2>
void For_each(const T* arr, int cnt, T2 t2)
{
    for (auto i = 0; i < cnt; ++i)
    {
        t2(arr[i]);
    }
}
int main()
{
    int arr[] = { 9,6,5,2,3,1,4,7 };
    int*p = arr;
    For_each(p, sizeof(arr) / sizeof(arr[0]), [&](const int& num)
    {
        cout << num << " ";
    });
    cout << endl;
    return 0;
}


使用仿函数求数组的和

struct Sum //仿函数
{
private:
    int total = 0;
public:
    void operator()(int val)
    {
        total += val;
    }
    void output() const
    {
        cout << "total = " << total << endl;
    }
};
template<class T, class T2>
T2 For_each(const T* arr, int cnt, T2 t2)
{
    for (int i = 0; i < cnt; ++i)
    {
        t2(arr[i]);
    }
    return t2;
}
int main()
{
    int arr[] = { 6,5,3,2,1,9,8,74 };
    Sum sum = For_each(arr, 8, Sum());
    sum.output();
    return 0;
}
目录
相关文章
|
7月前
|
算法 编译器 C++
【C/C++ 泛型编程 应用篇】C++ 如何通过Type traits 判断 Lambda表达式类型?
【C/C++ 泛型编程 应用篇】C++ 如何通过Type traits 判断 Lambda表达式类型?
147 4
|
7月前
|
编译器 C++
C++系列七:表达式
C++系列七:表达式
|
1月前
|
算法 编译器 C++
【C++11】lambda表达式
C++11 引入了 Lambda 表达式,这是一种定义匿名函数的方式,极大提升了代码的简洁性和可维护性。本文详细介绍了 Lambda 表达式的语法、捕获机制及应用场景,包括在标准算法、排序和事件回调中的使用,以及高级特性如捕获 `this` 指针和可变 Lambda 表达式。通过这些内容,读者可以全面掌握 Lambda 表达式,提升 C++ 编程技能。
74 3
|
3月前
|
算法 编译器 程序员
C++ 11新特性之Lambda表达式
C++ 11新特性之Lambda表达式
20 0
|
7月前
|
C++
【C/C++ 编程 入门篇】 if条件判断表达式的使用教程
https://developer.aliyun.com/article/1465430
145 0
|
5月前
|
安全 编译器 C++
C++一分钟之-泛型Lambda表达式
【7月更文挑战第16天】C++14引入泛型lambda,允许lambda接受任意类型参数,如`[](auto a, auto b) { return a + b; }`。但这也带来类型推导失败、隐式转换和模板参数推导等问题。要避免这些问题,可以明确类型约束、限制隐式转换或显式指定模板参数。示例中,`safeAdd` lambda使用`static_assert`确保只对算术类型执行,展示了一种安全使用泛型lambda的方法。
73 1
|
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++代码。
59 13
|
6月前
|
C++
C++语言的lambda表达式
C++从函数对象到lambda表达式以及操作参数化
|
6月前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
45 3
|
6月前
|
C语言 C++ 容器
c++primer plus 6 读书笔记 第五章 循环和关系表达式
c++primer plus 6 读书笔记 第五章 循环和关系表达式