c++0x 学习笔记之 lambda

 转:http://feng.free.lc/?m=201104

 

有了 lambda 的支持之后,写一些函数式的代码更加方便了,比如

std::vector<int> vec;
std::for_each( vec.begin(), vec.end(),
               [](int i){ std::cout <<i << "\t"; } );

再比如

std::sort( vec.begin(), vec.end(), [](int i, int j)
           { return std::abs(i) < std::abs(j); } );

其中的

[](int i, int j){return std::abs(i) < std::abs(j);}

就是一个 lambda 对象。这个匿名对象返回的类型是

decltype(std::abs(j)<std::abs(j))

需要特别说明的是,只有当 lambda 对象中有 return expression 时,返回类型才可以忽略,否则就是 void。因此,这个 lambda 对象完全写下来是这样的:

[](int i, int j) -> bool
{ return std::abs(i) < std::abs(j); }

这其中的 [] 称为 lambda 导引符(lambda-introducer),里边可以是空的,也可以有几个变量名称:


[] // 未定义任何参数
[x, &y] // x 以值传入,y 以引用传入
[&] //所有外部参数皆以引用传入
[=] // 所有外部参数皆以值传入
[&, x] // x 以值传入,其余以引用传入
[=, &z] // z 以引用传入,其余以值传入

下边是一个使用外部参数的例子

std::vector<double> arr;
double sum = 0;
std::for_each( arr.begin(), arr.end(),
               [&sum](double d){ sum += std::exp(d); } );

其中 sum 以引用传入,相当于计算

S = \sum_{i=1}^{i=N} e^{A_i}

并将结果存入 sum 中。

当然,上边也可直接抓取所有外部参数的引用做简化,这在参数很多的时候很有用

 

std::for_each( arr.begin(), arr.end(),
               [&](double d) { sum+= std::exp(d); } );

 

而 lambda 表达式中的 () 中的子参数(parameter-declaration-clause),在个数为 0 的时候可以忽略掉。

因此下边这一句无聊的代码也可以通过编译

[]{}();

其中 []{} 声明了一个匿名的 lambda 对象,抓取 0 个参数,传入 0 个子参数,不执行任何动作就返回 void 了,也就是

[]()->void{}

而加上后边的 () 表示这个 lambda 对象执行了一次。

 

如果在一个类中, lambda 需要抓取类的其它对象,这时候需要使用 [this], 比如

int f();
struct s
{
int i;
void g()
{
    [this]{ this->i += f(); }();
}
};

要注意上边例子中对 i 的操作是通过 this->i 实现的,直接对 i 操作会报错。

 

其实,c++0x 中引入的 auto 跟 lambda 配合得很好,下边代码可以让 lambda 匿名对象不再匿名了

auto hoo = []{};

使用时直接这样就好

hoo();

跟普通类型一样操控

auto goo = new auto([]{});

 

下方有熊出没,谨慎移步围观。

 

匿名 lambda 对象作为函数缺省对象时,无论是什么外部参数,无论是显式传入还是隐式传入,都是错误的。比如

void f2()
{
  int i = 1;
  void g1(int = ([i]{ return i; })()); // ill-formed
  void g2(int = ([i]{ return 0; })()); // ill-formed
  void g3(int = ([=]{ return i; })()); // ill-formed
  void g4(int = ([=]{ return 0; })()); // OK
  void g5(int = ([]{ return sizeof(i); })()); // ill_formed
}

除非有 [this], 否则使用一个在 lambda 对象之外声明的,有生存期的变量或者引用是不合法的(use of a variable or reference with automatic storage duration declared outside the lambda-expression is ill-formed.)

void f1(int i)
{
  int const N = 20;
  [=]{
        int const M = 30;
        [=]{
             int x[N][M]; // OK: N and M are not "used"
             x[0][0] = i; // error: i is not declared in the immediately
             }; // enclosing lambda-expression
       };
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值