gpt4 book ai didi

「学习笔记」Lambda表达式

转载 作者:我是一只小鸟 更新时间:2023-07-10 14:31:06 30 4
gpt4 key购买 nike

Lambda 表达式因数学中的 \(\lambda\) 演算得名, 直接对应于其中的 lambda 抽象. Lambda 表达式能够捕获作用域中的变量的无名函数对象, 我们可以将其理解为一个匿名的内联函数, 可以用来替换独立函数或者函数对象, 从而使代码更可读. 但是从本质上来讲, Lambda 表达式只是一种语法糖, 因为它能完成的工作也可以用其他复杂的 C++ 语法来实现. 。


下面是 Lambda 表达式的语法结构. 。

                        
                          [capture] (parameters) mutable -> return-type {statement}

                        
                      

capture : 捕获,

parameters : 参数,

mutable : 可变规范,

return-type : 返回类型,

statement : Lambda 表达式的主体,


下面是更高版本的 C++ 的有关 Lambda 表达式的语法. [1] 。

                        
                          [capture] (parameters) lambda说明符 约束(可选) {statement}
[capture] {statement}    // (C++23 前)
[capture] lambda说明符 {statement}    // (C++23 起)
[capture] < 模板形参 > 约束(可选) // (C++20 起)
(parameters) lambda说明符 约束(可选) {statement}    // (C++20 起)
[capture] < 模板形参 > 约束(可选) {statement}    // (C++20 起 C++23 前)
[capture] < 模板形参 > 约束(可选) lambda说明符 {statement}    //(C++23 起)

                        
                      

capture 捕获

捕获 是一个含有零或更多个 捕获符 的逗号分隔列表, 可以  默认捕获符  开始. 默认捕获符只有两种

  • & (以引用隐式捕获被使用的自动变量).
  • = (以复制隐式捕获被使用的自动变量).

当出现任一默认捕获符时, 都能隐式捕获当前对象(*this). 如果隐式捕获它, 那么会始终以引用捕获,即使默认捕获符是  = . 当默认捕获符为  =  时, *this 的隐式捕获被弃用. (C++20 起) 。

当默认捕获符是  &  时, 后继的简单捕获符不能以  &  开始. 。

                        
                          struct S2 { void f(int i); };
void S2::f(int i)
{
    [&]{}; // OK:默认以引用捕获
    [&, i]{}; // OK:以引用捕获,但 i 以值捕获
    [&, &i] {}; // 错误:以引用捕获为默认时的以引用捕获
    [&, this] {}; // OK:等价于 [&]
    [&, this, i]{}; // OK:等价于 [&, i]
}

                        
                      

当默认捕获符是  =  时, 后继的简单捕获符必须以  &  开始, 或者为 *this (C++17 起) 或 this (C++20 起). 。

                        
                          struct S2 { void f(int i); };
void S2::f(int i)
{
    [=]{}; // OK:默认以复制捕获
    [=, &i]{}; // OK:以复制捕获,但 i 以引用捕获
    [=, *this]{}; // C++17 前:错误:无效语法
    // C++17 起:OK:以复制捕获外围的 S2
    [=, this] {}; // C++20 前:错误:= 为默认时的 this
    // C++20 起:OK:同 [=]
}

                        
                      

任何捕获符只可以出现一次, 并且名字不能与形参相同

                        
                          struct S2 { void f(int i); };
void S2::f(int i)
{
    [i, i] {}; // 错误:i 重复
    [this, *this] {}; // 错误:"this" 重复(C++17)
    [i] (int i) {}; // 错误:形参和捕获的名字相同
}

                        
                      

parameters 参数

大多数情况下类似于函数的参数列表. 。

C++14  中, 若参数类型是泛型, 则可以使用  auto  声明类型

                        
                          int x[] = {5, 1, 7, 6, 1, 4, 2};
std::sort(x, x + 7, [](int a, int b) { return (a > b); });
for (auto i : x) std::cout << i << " ";

                        
                      

这份代码将打印出 x 数组从大到小排序后的结果. 。

mutable 可变规范

利用可变规范, Lambda 表达式的主体可以修改通过值捕获的变量. 若使用此关键字, 则 parameters  不可省略 (即使为空). 。

一个例子, 使用  capture 捕获字句  中的例子, 来观察 \(a\) 的值的变化

                        
                          int a = 0; 
auto func = [a]() mutable { ++a; };

                        
                      

此时 lambda 中的 \(a\) 的值改变为 \(1\) , lambda 外的 \(a\) 保持不变. 。

return-type 返回类型

用于指定 Lambda 表达式的返回类型. 若没有指定返回类型, 则返回类型将被自动推断 (行为与用  auto  声明返回值的普通函数一致). 具体的, 如果函数体中没有  return  语句, 返回类型将被推导为  void , 否则根据返回值推导. 若有多个  return  语句且返回值类型不同, 将产生编译错误. 。

                        
                          auto lam = [](int a, int b) -> int

                        
                      

statement Lambda 主体

Lambda 主体可包含任何函数可包含的部分。普通函数和 Lambda 表达式主体均可访问以下变量类型:

  • 从封闭范围捕获变量
  • 参数
  • 本地声明的变量
  • 在一个  class  中声明时,若捕获  this ,则可以访问该对象的成员
  • 具有静态存储时间的任何变量,如全局变量

  1. 该资料来自 Lambda表达式(C++11起)-cppreference.com ↩︎ 。

最后此篇关于「学习笔记」Lambda表达式的文章就讲到这里了,如果你想了解更多关于「学习笔记」Lambda表达式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com