IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C11中的新特性----lambda表达式 -> 正文阅读

[C++知识库]C11中的新特性----lambda表达式

lambda表达式

lambda来源于函数式编程的概念,是现代编程语言的一个特点。
lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量

lambda表达式的基本功能和语法形式

[cature] (params)opt->ret{body;};
//capture是捕获列表;params是参数表;opt是函数选项;ret是返回值类型;body是函数体。
//lambda表达式可以通过捕获列表捕获一定范围内地变量。
  1. **[ ];**不捕获任何变量。
  2. **[ & ];**捕获外部作用域中的所有变量,并作为引用在函数体中使用(按引用捕获)。
  3. **[ = ];**捕获外部作用域中的所有变量,并作为副本在函数体中使用(按引用值捕获)。
  4. **[ = , &foo ];**按值捕获外部作用域中的所有变量,并作为引用捕获foo变量。
  5. **[ bar ];**按值捕获bar变量,同时不捕获其他变量。
  6. **[ this ];**捕获当前类中的this指针,让lambda表达式拥有和其他类成员函数同样的访问权限。如果已经使用了&或=,就默认添加此选项。捕获this的目的是可以在lamda中使用当前类的成员函数和成员变量。

lambda表达式的优点

  1. 声明式编程风格:就地匿名定义目标函数或者函数对象,不需要额外写一个命名函数或者函数对象。以更直接的方式去写程序,有高的可读性和维护性
  2. 简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和功能分散,让开发者更加集中精力工作时,也获得了更高的生产率。
  3. 在需要的时间和地点实现功能闭包,使程序更加灵活。

案例说明


int g_max = 10;
class Object
{
private:
    int value;
public:
    Object(int x = 0) :value(x)
    {
        cout << "Create Object" << this << endl;
    }
    void func(int a, int b)
    {
        //error,没有捕获外部变量
        auto x1 = []()->int
        {
           // return a;
        };
        //捕获外部作用域中所有变量,按值捕获(包括全局变量和this指针)
        auto x2 = [=]()->int
        {
            int x = value;
            return x + a + g_max;
        };
        //捕获外部作用域中所有变量,按引用捕获(包括全局变量和this指针)
        auto x3 = [&]()->int
        {
            g_max = 100;
            value += 10;
            return g_max + value;
        };
        //只是捕获this指针
        auto x4 = [this](int c)->int
        {
            value += 100;
            return value + c;
        };
        //error,只是捕获this指针,不捕获a,b
        auto x5 = [this]()->void
        {
           // value = a + b;
        };
        //只是捕获this指针,a,b
        auto x6 = [this, a, b]()->void
        {
            value = a + b;
        };
    }
};

总结

默认状态下lambda表达式无法修改通过复制方式捕获的外部变量。如果希望修改这些变量的话,我们需要使用引用方式进行捕获。

案例2

typedef void (*ptr)(int);

int main()
{
    int a = 10, b = 20;

    auto f1 = [](int a)->void
    {
        cout << a << endl;
    };

    auto f2 = [](int x)->void
    {
        cout << x + 10 << endl;
    };

    auto f3 = [=]()->int
    {
        return a++;//error,=改为&即可
    };
    auto f4 = [=]()mutable->int
    {
        return a++;//OK
    };
    auto f5(f1);//OK
    f1 = f2;//error,lambda表达式之间不能赋值
    ptr p1 = f1;//OK
    auto f4 = [=](int x)->void
    {
        cout << "hello" << endl;
    };
    ptr p2 = f4;//error

}

总结

被mutable修饰的lambda表达式就算没有参数也要写明参数列表
lambda表达式可以说是就地定义仿函数闭包的“语法糖”。他的捕获列表捕获住的任何外部变量,最终均会变为闭包类型的成员变量。而一个使用了成员变量的类的operator(),如果能直接被转换为普通的函数指针,那么lambda表达式本身的this指针就丢失了。而没有捕获任何外部变量的lamba表达式则不存在这个问题。
这里也可以很自然地解释为什么按值捕获无法修改捕获的外部变量。在C++中,lambda表达式的operator()默认是const的方法。一个const成员函数是无法修改成员变量的值的。而mutable的作用,就在于取消operator()的const。
没有捕获变量的lambda表达式可以直接转换为函数指针,而有捕获变量的lambda表达式则不能转换为函数指针。

案例3

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:31:36  更:2022-04-14 23:34:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:11:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码