1.Lambda的语法

所谓lambda是一份功能定义式,可以被定义于语句(statement)或表达式(expression)内部,因此可以将lambda当作inline函数使用。[]叫做introducer,可以在内部指明一个所谓的capture,用来在lambda内部访问nonstatic外部对象

int main()
{
	//定义一个lambda,但没有进行调用
	[] {
		std::cout << "hello lambda!" << endl;
	};
	//定义一个lambda并进行调用
	[] {
		std::cout << "hello lambda1!" << endl;
	}();
	//或者将它传给一个对象
	auto l = [] {
		std::cout << "hello lambda1!" << endl;
	};
	l(); //调用
	cout << sizeof(l) << endl; //answer = 1
	return 0;
}

在lambda introducer和lambda body之间,可以指明参数或mutable,或一份异常明细或attribute specifier以及返回类型。这些是可有可无的,如果出现了,参数所需的小括号就必须出现

lambda语法
1.[...] {...}
2.[...] (...) mutable throwSpec ->retType {...}
lambda可以拥有参数,指明在小括号内
auto l = [] (const string& s) {
    cout << s << endl;
};
l("hello");  

lambda不可以是template,必须始终指明所有类型。

lambda也可以返回某物,但不需要指明返回类型,该类型会根据返回值被推导出来。

int main()
{
	// 1.lambda可以返回某物,不用指明类型,可以自动推导
	auto l = [] {
		return 123;
	};
	int ans = l();
	cout << ans << endl;
	// 2.也可以指明一个返回类型
	auto l2 = []() -> double { //注意()
		return 123;
	};
	double ans2 = l2();
	cout << ans2 << endl;
	return 0;
}

2.Capture(用以访问外部作用域)

在lambda最开始的方括号内,可以指明一个capture用来处理外部作用域内未被传递为实参的数据:

int main()
{
	int x = 0;
	int y = 42;
	auto l = [x, &y] {
		// x以by value形式传递, y以by reference方式传递
		cout << "x: " << x << endl; //0
		cout << "y: " << y << endl; //42
		//x++; //error
		y++; //ok
	};
	l();
	cout << "final y: " << y << endl; //43
	return 0;
}

为了得到passing by reference和value的混合体,可以声明lambda为mutable。意思是以by value传递,但是可以在lambda中修改传入的值。

int main()
{
	int x = 0;
	int y = 42;
	auto l = [x, &y]() mutable {
		// x以by value形式传递, y以by reference方式传递
		cout << "x: " << x << endl; //0
		cout << "y: " << y << endl; //42
		x++; //ok
		y++; //ok
	};
	l();
	cout << "final x: " << x << endl; //0
	cout << "final y: " << y << endl; //43
	return 0;
}

3.Lambda的类型

lambda的类型,是一个不具名的function object(或者说functor)。每个lambda表达式的类型是独一无二的。因此如果想根据该类型声明对象,可以借助template或者auto,如果实在需要写下这个类型,可以借助decltype().例如将lambda作为hash function或ordering准则或sorting准则传给容器。

也可以使用C++STL提供的function<>class template指明一个一般化类型给functional programming使用。这个class template提供了"明确指出函数的返回类型为lambda"的唯一办法。

#include <iostream>
#include <functional>
using namespace std;
function<int(int, int)> returnLambda() {
	return [](int x, int y) {
		return x * y;
	};
}
int main()
{
	auto lf = returnLambda();
	cout << lf(5, 7) << endl;
	return 0;
}