浅析lambda表达式

c++11以前的函数对象

c++11以前的函数对象通常使用重载了()运算符的结构来实现。

例子中定义了一个拥有固定累加值成员的adder,通过构造一个对象,调用adder的operator()来实现函数调用。

struct adder {
  adder(int n) : n_(n) {}
  int operator()(int x) const
  {
    return x + n_;                                                                                                                     
  }
private:
  int n_; 
};

int main()
{
    auto sumer = adder(2);
    cout<<sumer(1)<<endl;//输出3
    return 0;
}

c++11的函数对象--lambda

lambda是c++11中出现的匿名函数对象,它以[]开始,以{}结束。

例子中是一个和上面功能一样的lambda表达式

auto adder = [](int x) {
    return x + 2;
};

int main()
{
    cout<<adder(1)<<endl;
    return 0;
}

lambda表达式的存储:每一个 lambda 表达式都是一个单独的类型,所以只能使用 auto 或function<T>来接收结果。

():表示lambda表达式的函数入参,如果没有入参可以忽略

{}:表示lambda的函数体

->:返回值类型,如果返回值类型为void或者可以通过推到得到,可以省略

auto lamb = [a](int x)->int {
    return x+a;
}

[]:表示lambda对变量的捕获方式,具体的捕获方式如下:

  • []:默认不捕获任何变量;
  • [=]:默认以值捕获所有变量(在非静态成员函数中,自动按引用捕获this);
  • [&]:默认以引用捕获所有变量(在非静态成员函数中,自动按引用捕获this);
  • [x]:仅以值捕获x,其它变量不捕获;
  • [&x]:仅以引用捕获x,其它变量不捕获;
  • [=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获;
  • [&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获;
  • [this]:通过引用捕获当前对象(针对在非静态成员函数中使用lambda);
  • [*this]:通过传值方式捕获当前对象(c++17,针对在非静态成员函数中使用lambda);
  • [x = 表达式]:按值捕获表达式(c++14)
  • [&x = 表达式]:按引用捕获表达式(c++14)

捕获表达式中lambda对象func相当于保存了一个名叫tm的数据成员,在生成lambda表达式时进行初始化。

auto func = [tm = time()]() {
    cout<<"current utc:"<<tm<<endl;
}

从工程的角度,大部分情况不推荐使用默认捕获符。更一般化的一条工程原则是:显式的代码比隐式的代码更容易维护。一般而言,按值捕获是比较安全的做法。按引用捕获时则需要更小心些,必须能够确保被捕获的变量和 lambda 表达式的生命期至少一样长,并在有下面需求之一时才使用:

  • 需要在 lambda 表达式中修改这个变量并让外部观察到
  • 需要看到这个变量在外部被修改的结果
  • 这个变量的复制代价比较高

如果希望以移动的方式来捕获某个变量的话,则应考虑 变量名 = 表达式 的形式。表达式可以返回一个 prvalue 或 xvalue,比如可以是 std::move(需移动捕获的变量)。

mutable:标记捕获的内容可以被更改,默认情况下不可修改,因为lambda的()运算符重载函数默认是const的。

auto change = [age]() mutable {
    ++age;
}

泛型lambda表达式

相比于普通函数定义只有返回值可以以auto声明,lambda表达式可以对函数参数也使用auto声明。

auto lamb2 = [](auto x , auto y) {
    return x + y;
}

补充资料

https://zh.wikipedia.org/zh-cn/ 函数对象

https://zh.wikipedia.org/zh-cn/ 匿名函数

https://www.jianshu.com/p/d686ad9de817

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值