lambda表达式解析
什么是lambda表达式
lambda表达式是一个可调用的代码单元,可以将其理解为一个未命名的内联函数。
lambda表达式形式:
[捕获列表](参数列表)-> return type{函数体}
其中参数列表和return type可以省略:
auto f=[]{return 42;};
我们经常在排序中使用:
1 2 3 4 5
| vector<string> words={"aa","bbbb","ccccc"}; stable_sort(words.begin(),words.end(),[](const string &a,const string &b){return a.size()<b.size();});
return 0; }
|
初步分析
我们借助c++ insight工具对其实现原理进行分析
1 2 3 4 5 6 7 8
| #include <cstdio> #include<string> using namespace std;
int main() { auto fun=[](string a,string b){return a.size()<b.size() ;}; }
|
被编译器转换为:
编译器会将lambda函数转成一个类:class
__lambda_7_12,并inline的重载操作符函数
using retType_7_12 = bool (*)(string, string);
这一行创建了一个名为retType_7_12
的类型别名。该别名表示一个指向接受两个string
参数并返回bool
的函数的指针。using
关键字用于为更好的代码可读性和可维护性定义此类类型别名
实际上fun是一个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <cstdio> #include<string> using namespace std;
int main() { class __lambda_7_12 { public: inline bool operator()(std::basic_string<char> a, std::basic_string<char> b) const { return a.size() < b.size(); } using retType_7_12 = bool (*)(string, string); inline constexpr operator retType_7_12 () const noexcept { return __invoke; }; private: static inline bool __invoke(std::basic_string<char> a, std::basic_string<char> b) { return __lambda_7_12{}.operator()(a, b); } }; __lambda_7_12 fun = __lambda_7_12{}; return 0; }
|
使用捕获列表
Lambda 表达式可以使用上下文的变量
下面的函数可以用于输出长度大于sz的字符串(c++ primer 349)
1 2 3 4 5 6
| void bigger(vector<string> &words,vector<string>::size_type sz,ostream &os =cout){ stable_sort(words.begin(),words.end()); auto bigit=find_if(words.begin(),words.end(),[&sz](const string & a){return a.size()>sz;}); for_each(bigit,words.end(),[&os](const string &s){os<<s<<" ";}); os<<endl; }
|
值捕获