在刷牛客时,看到这段lambda表达式可以提高输入输出速度
1 static const auto io_sync_off = []() 2 { 3 // turn off sync 4 std::ios::sync_with_stdio(false); 5 // untie in/out streams 6 std::cin.tie(nullptr); 7 return nullptr; 8 }();
于是去详细了解C++11引入的 Lambda 表达式,和大家分享。
1、Lambda
lambda的类型是一个匿名的函数对象
// 作为 inline function, 可以作为参数或者无名对象 []{ std::cout << "Hello Lambda" << std::endl; } ----------------------------------------------------- // 单独写出来,调用 auto I = []{ std::cout << "Hello Lambda" << std::endl; }; ... I(); // 打印 "Hello Lambda"
标准的定义形式:
[...](...)mutable throwSpec ->retTpye{...}
其中:
mutable/throwSpec/->retType 都是可选的,但只要有一个,前面就得有()
[...] 这里面写外部变量,可以传值,也可以传引用;
(...) 这里是正常的参数列表,可以传值,也可以传引用;
mutable 可变的,如果对外部变量要进行修改的话必须加上;
throwSpec 抛出异常
->retType 如果包含return以外的任何语句,默认返回void; 特殊的,若要有返回类型,则必须尾置返回指定类型 ->return type
// 写的清楚点就是 [captrue list] (parameter list) -> return type { function body }
2、体会下[...] (...)的不同以及常规用法
1 class Functor{ 2 public: 3 void operator()(){ 4 cout << "id:" << id << endl; 5 ++id; 6 } 7 private: 8 int id; 9 }; 10 11 int main(){ 12 int id1 = 0; 13 // 这里必须写mutable,表示可变的; 14 // 这个表达式和上面的Functor等价,相当于一个匿名函数对象 15 auto f = [id1]()mutable{ 16 cout << "id1:" << id1 << endl; 17 ++id1; 18 }; 19 id1 = 42; 20 f(); 21 f(); 22 f(); 23 cout << id1 << endl; 24 cout << "------------------" << endl; 25 26 int id2 = 42;
//这里传引用进来 &id2 ¶m,观察下这两个值的变化,注意这里传的是引用就别mutable 27 auto f2 =[&id2](int ¶m){ 28 cout << "id2:" << id2 << " param:" << param << endl; 29 ++id2; 30 ++param; 31 }; 32 int param = 6; 33 f2(param); 34 f2(param); 35 f2(param); 36 cout << id2 << " " << param << endl; 37 38 return 0; 39 }
// 代码执行结果 id1:0 id1:1 id1:2 42 ------------------ id2:42 param:6 id2:43 param:7 id2:44 param:8 45 9
可以看做是一个匿名函数的调用
auto func1 = [](const string &a, const string &b){ return a.size() > b.size(); } //等价于 class NoNameClass{ public: bool operator()(const string &a, const string &b){ return a.size() > b.size(); } };
3、具体应用
可以定义准则,来配合STL容器使用
4、注意点
(1)参数列表不能有默认值
(2)可以省略参数列表和返回类型(默认void),但必须有捕获列表和函数体; []{return 1;}
(3)如果包含return以外的任何语句,默认返回void; 特殊的,若要有返回类型,则必须尾置返回指定类型 ->return type
1 // 包含多个语句,且需要返回int,就必须尾置类型 2 auto f = [](int i) ->int { 3 if(i<0) return -i; 4 else return i; 5 }
(4)