概念

  • 谓词
    • 可调用的表达式
  • lambda表达式
    • 一个可调用的代码单元
    • 一个未命名的内联函数

lambda表达式

  • 形式

    • [ capture list ] (parameter list) -> return type
  • 捕获列表

    • lambda所在函数中定义的局部变量列表
    • 可直接使用局部static变量和lambda所在函数之外声明的名字
  • 参数列表

    • 可忽略
    • 不能有默认参数
    • 逗号分隔
    • 可捕获在创建lambda表达式的作用域内可风的 非静态 局部变量
      • 依赖于所捕获的这些局部变量
      • 同时也依赖于lambda表达式形参
    • 还可以直接使用静态存储期对象
      • 也会依赖于这些对象
    • 空捕获
      • []
    • 默认捕获(值捕获)
      • [names]
    • 显式捕获
      • 值捕获
        • [=, identifier_list]
        • 捕获变量的值是在lambda创建时拷贝
        • 对应着闭包类中的数据成员
      • 引用捕获
        • [&, identifier_list]
        • 无须在闭包类中将其存储为数据成员
    • 隐式捕获
      • 让编译器根据lambda体中的代码推断要使用哪些变量
        • [&]
          • 注意空悬引用
        • [=]
          • 不推荐使用
    • 混合捕获
      • [=, &os]、[=, identifier_list]、[&, identifier_list]等
    • 捕获当前对象
      • 显示捕获this
      • 出现任一种捕获类型时:[&, ... ]、[=, ... ]、[&]、[=],当前对象都默认是以引用方式被捕获,并且访问成员变量时不需要以this->调用
    • 伪初始化捕获
      • c++11中使用std::bind实现
    • 初始化捕获
      • c++14
  • 返回类型

    • 可忽略
    • 必须尾置返回
  • 函数体

  • 定义

    • 当定义一个lambda时,编译器生成一个与lambda对应的新的(未命名)类类型,闭包类
      • 这个新类型的数据成员也是在lambda对象被创建时初始化
      • 默认情况下,lambda生成的闭包类中的operator()成员函数会带有const饰词
        • lambda表达式的声明中可以显式指定mutable:
    • 当向一个函数传递一个lambda时,同时定义了一个新类型(闭包类)和该类型的一个对象(闭包):传递的参数就是此编译器生成的类类型的未命名对象
    • 当使用auto定义一个用lambda初始化的变量时,定义了一个从lambda生成类型的对象

其他相关语言特性

decltype

  • 背景

    • 从表达式的类型推断出要定义的变量的类型,但不想用该表达式的值初始化变量
  • 概念

    • 一种类型说明符
    • 选择并返回操作数的数据类型
    • c++11中主要用途大概就在于:声明那些 返回值型别 依赖于 形参型别 的 函数模板
  • decltype使用的表达式:

    • 是一个变量
      • 返回该变量的类型
    • 不是一个变量
      • 返回表达式结果对应的类型
        • 如表达式的内容是解引用操作, 则decltype将得到(左值)引用类型
    • 一些特殊情况:比仅有名字更复杂的左值表达式(不仅是一个型别为T的名字)
      • 得出的型别总是左值引用(对于型别为T的左值表达式,除非该表达式仅有一个名字,否则decltype总是得出型别T&)
        • 如int x = 0;时decltype((x))的结果成了int&

尾置返回类型

  • 本应该出现返回类型的地方放置一个auto,形如:
    • auto func( int i ) -> int(*)[10]

泛型lambda表达式

  • 在形参规格中使用auto
    • c++14

lambda表达式可变长形参

  • c++14

参考

Lambda expressions (since C++11)
《C++ Primer(第五版)》
《Effective Modern C++》

posted on 2020-03-22 22:16  chenguang9239  阅读(157)  评论(0编辑  收藏  举报