C++在函数中也能定义函数?当让不可能,但是定义函数对象却是可以的。如果用旧的方法定义一个函数对象,那就要自己编写一个函数类,这样不够方便。但是C++ 11发布后,在函数内简便地定义“函数”(其实是『函数对象』)成为了可能。
下面是一个简单的样例,其中在main
函数内部定义了两个『函数对象』,一个是print
用来打印二维vector;另一个是cmp
用来为sort函数提供排序标准,即根据第二个元素的大小从大到小排列。
#include
#include
#include
using namespace std;
int main()
{
auto print = [](vector<vector<int>> a) {
for(int i=0;i<a.size();i++) {
for(int j=0;j<a[i].size();j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
};
vector<vector<int>> A;
vector<int> B({1,2}); A.push_back(B);
B=vector<int>({2,1}); A.push_back(B);
B=vector<int>({3,6}); A.push_back(B);
cout<<"----------Origin---------"<<endl;
print(A);
auto cmp = [](const vector<int> a, const vector<int> b){return a[1]>b[1];};
sort(A.begin(), A.end(), cmp);
cout<<"----------After Sorted---------"<<endl;
print(A);
getchar();
return 0;
}
结果输出为:
----------Origin---------
1 2
2 1
3 6
----------After Sorted---------
3 6
1 2
2 1
对于这种写法的解释:
auto
并不是旧标准中自动变量的意思(自动分配和自动释放空间),它在C++ 11中赋予了新的功能:当变量被声明时,从变量的初始化值中推出并指定变量的类型。auto print = [](xx) { };
是一个省去-> ret
的 Lambda 表达式,下面会详细介绍Lambda 表达式。lambda 来源于函数式编程的概念,也是现代编程语言的一个特点。C++11 终于把 lambda 加入了进来。
lambda表达式有如下优点:
lambda 表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。lambda 表达式的语法形式可简单归纳如下:
[ capture ] ( params ) opt -> ret { body; };
其中
&
表示捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获);=
表示捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获);=,&foo
表示按值捕获外部作用域中所有变量,并按引用捕获 foo
变量。bar
按值捕获 bar
变量,同时不捕获其他变量;this
表示捕获当前类中的 this 指针,让 lambda 表达式拥有和当前类成员函数同样的访问权限。如果已经使用了 &
或者 =
,就默认添加此选项。捕获 this 的目的是可以在 lamda 中使用当前类的成员函数和成员变量。