Lambda函数到底是个什么

1 什么是Lambda函数

lambda函数是指简单的代码片段,通常认为是不值得命名的函数,它不能重复使用,能方便程序员使用,增强代码可读性,降低代码出错概率。

[ 捕获列表 ] (参数) -> 返回类型 {}

编译器通常会计算lambda函数的返回类型,所以一般不需要指定返回类型,但少数情况编译器可能无法判断返回类型,还是需要指定返回类型。

2 为什么要使用Lambda函数

c++定义了许多标准库函数,比如std::for_each,用来循环

int main()
{
	std::vector<int> v = {1, 2, 3, 4, 5};
	std::for_each(v.begin(), v.end(), print());
	return 0;

如果只是在特定的地方使用一次的函数,还要编写一个完整的方法就会显得繁琐。
对于上面的这种使用场景,我们可以使用Lambda函数来实现。

std::for_each(v.begin(), v.end(), [](int element) {cout << element;} );

3 Lambda内部是如何工作的 (核心)

[&i] () { std::cout << i; }

struct anonymous
{
	int &m;
	anonymous(int &i) : m_i(i) {}
	inline auto operator()() const
	{
		std::cout << i;
	}
}

编译器为每个Lambda函数生成了如上的唯一闭包,捕获列表将成为闭包中构造函数的参数,如果是按引用捕获,那么对应数据类型的成员会在闭包中创建。

4 使用的好处

Lambda函数对代码的性能没有影响,反而能够使代码结构更加紧凑、易读,代码的编写更加方便。

5 使用Lambda表达式

int main()
{
	int x = 100;
	int y = 200;
	auto print = [&] {
					std::cout << __PRETTY_FUNCTION__ << " : " 
					<< x << " , " << y << std::endl;
					};
	print();
	return 0;
}

上面的代码可以输出

auto main()::(anonymous class)::operator()() const : 100 , 200

6 Lambda函数捕获列表

捕获列表 意义
[ ] ( ) { } 不捕获外接变量
[=] ( ) { } 所有都按值捕获
[&] ( ) { } 所有都按引用捕获
[x] ( ) { } x按值捕获
[&x] ( ) { } x按引用捕获
[&,x] ( ) { } x按值捕获,其它的按引用捕获
[=,&x] ( ) { } x按引用捕获,其它的按值捕获
std::vector<int> v1;
int total = 0;
int value = 5;
std::for_each(begin(v1), end(v1), [&, value](int x) 
{
  total = x * value;
});

在这个例子中,value会被按值捕获,会存储一份拷贝的值,total会以引用的方式捕获,

可以使用auto帮助存储lambda函数

auto lambda_func_1 = [&](int x) {  };
auto removeListenerInVector = [&](std::vector<EventListener*>* listeners){
        if (listeners == nullptr)
            return;
        
        for (auto iter = listeners->begin(); iter != listeners->end(); ++iter)
        {
            auto l = *iter;
            if (l == listener)
            {
                CC_SAFE_RETAIN(l);
                l->setRegistered(false);
                if (l->getAssociatedNode() != nullptr)
                {
                    dissociateNodeAndEventListener(l->getAssociatedNode(), l);
                    l->setAssociatedNode(nullptr);  // nullptr out the node pointer so we don't have any dangling pointers to destroyed nodes.
                }
                
                if (_inDispatch == 0)
                {
                    iter = listeners->erase(iter);
                    releaseListener(l);
                }
                else
                {
                    _toRemovedListeners.push_back(l);
                }
                
                isFound = true;
                break;
            }
        }
    };

还可以把lambda函数存储在变量、数组和vector中,把他们当作命名参数来传递

#include<functional>
#include<vector>
#include<iostream>
double eva(std::function<double(double)> f, double x = 2.0){return f(x);}
int main()
{
     std::function<double(double)> f0    = [](double x){return 1;};
     auto                          f1    = [](double x){return x;};
     std::cout << eva(f0) << "\n";
     std::cout << eva(f1) << "\n";
     return 0;
}
原文地址:https://www.cnblogs.com/sakuraneo/p/11992055.html