1 lambda的捕获列表 类似于 bind 的参数绑定:将定义lambda定义处的绑定的变量值作为该lambda的固定参数。

e.g

void callfunction()
{
int dd=100;
int ee=200;
auto lam= [dd,ee](int param1)->int{return dd+ee+param1;}; ------1

1处在定义lambda的地方 dd,ee 就给定了 是100,200;则在调用该lambda表达式时 dd,ee 就分别时100,200;

//call 
int para =300;

lam(para);/* 实际执行 100+200+300*/

}

2 lambda 的mutable关键字可以修改传到lambda定义体之内的变量的值,但该改变不能传递到定义体之外 。慎用mutable

int var=5;

int z=varmutable->int{
var++;
in n=3;
return var;
}();

cout <<"var:="<<var<<std::endl;

输出 var :=5 而不是 var 6

3 lambda 的代码膨胀

e.g
`std::list coll ={1,2,3,4,5,6,7,8,9,10};
std::list::iterator pos;
int count =0;
pos = remove_if(coll.begin(),coll.end(),count mutable {
++count;
return (count==3);
});

coll.erase(pos,coll.end());
for each (int var in coll)
{
std::cout << var <<";"<<std::endl; //
}`
输出结果 应为 1;2;4;5;6;7;8;9;10
实际是: 1;2;4;5;7;8;9;10
删除两次

原因:

首先来看 std::remove_if 的实现:


template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
    first = std::find_if(first, last, p);
    if (first != last)
        for(ForwardIt i = first; ++i != last; )
            if (!p(*i))
                *first++ = std::move(*i);
    return first;
}

会发现,被传入 remove_if 的 lambda 在算法内又被传递给了 find_if 这个算法。

由于 lambda 实际上是一个类的对象,所以复制一个 lambda 实际上复制了一个对象。

在这种情况下,find_if 复制了一次 lambda,造成两个 lambda 并不共享同一个 count,于是两个 count = 0 对应空格删除了两次。

这种情况就属于对 mutable 的滥用,换句话说,C++ 语法和算法库的特性导致算法只有在接收 const 的 lambda 作为参数时才能做到正确。

**换句话说,C++ 语法和算法库的特性导致算法只有在接收 const 的 lambda 作为参数时才能做到正确**
posted on 2024-03-06 09:21  keleman  阅读(1)  评论(0编辑  收藏  举报