C++11:lambda表达式

2019-11-30  本文已影响0人  fck_13
#include <iostream>
#include <string>
int main()
{
    std::string hello = "hello";
    auto hello_func = [hello](std::string name) mutable noexcept /*[[attr]]*/ -> void {std::cout << hello << ", " << name << "\n"; };
    hello_func("Leo");
    hello_func("Fan");
    return 0;
}

hello_func 是我们声明的一个匿名函数对象,它是可被调用的。

[hello](std::string name) mutable noexcept /*[[deprecated]]*/ -> void {std::cout << hello << ", " << name << "\n"; };

是一个lambda表达式,它的求值结果是一个匿名函数对象。这个lambda表达式的结构有些复杂,事实上,我们可以简化lambda表达式,最简形式为:[ 捕获 ] { 函数体 }
[hello]表示该lambda表达式捕获了hello这个变量。我们这里来讲一下捕获(capture)

  1. 若变量满足下列条件,则 lambda 表达式可以不捕获就使用它
    1.1 该变量为非局部变量,或具有静态或线程局部存储期(该情况下无法捕获该变量),或者
    1.2 该变量为以常量表达式初始化的引用。
  2. 若变量满足下列条件,则 lambda 表达式可以不捕获就读取其值
    2.1 该变量具有 const 而非 volatile 的整型或枚举类型,并已用常量表达式初始化,或者
    2.2 该变量为 constexpr 且无 mutable 成员。

(std::string name) 是形参列表。 如果在形参列表里使用auto来声明变量,那么该lambda表达式为generic lambda。我们可以简单的把这个形参列表理解为函数的形参列表,并没有啥不同。

mutable是函数的说明符,这个不是必须的。mutable在这里的意思是可以修改通过值捕获的变量,并调用它们的non-const函数。除此之外还有constexpr(C++ 17) 和consteval(C++ 20)。

noexcept为异常说明,其在这里的意思等价于noexcept(true)throw(),即不抛出异常。
[[attr]]这里本来是放置属性的,这里的属性是给closureType,而不是给lambda的表达式的。我没有找到一个合适的属性,所以就简单的注释掉了。尴尬
->void表明返回类型。如果不写的话返回值类型能被自动的推导出来。
std::cout << hello << ", " << name << "\n"; }为函数体。

lambda表达式为纯右值表达式。它的类型为ClosureType,是无名的,非联合的,非聚合的类型。

上一篇 下一篇

猜你喜欢

热点阅读