C++ 在函数中定义函数

C++在函数中也能定义函数?当让不可能,但是定义函数对象却是可以的。如果用旧的方法定义一个函数对象,那就要自己编写一个函数类,这样不够方便。但是C++ 11发布后,在函数内简便地定义“函数”(其实是『函数对象』)成为了可能。

Part.I 实例

下面是一个简单的样例,其中在main函数内部定义了两个『函数对象』,一个是print 用来打印二维vector;另一个是cmp用来为sort函数提供排序标准,即根据第二个元素的大小从大到小排列。

#include <iostream>
#include <algorithm>
#include <vector>

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

Part.II 解释

对于这种写法的解释:

  • 上面代码中的auto并不是旧标准中自动变量的意思(自动分配和自动释放空间),它在C++ 11中赋予了新的功能:当变量被声明时,从变量的初始化值中推出并指定变量的类型。
  • auto print = [](xx) { };是一个省去-> ret 的 Lambda 表达式,下面会详细介绍Lambda 表达式。
  • Lambda由于产生的是无名的函数对象,所以它并不能直接在函数中被调用。但如果『把这无名的函数对象起个别名』,那么就可以通过别名来调用了。

Chap.I Lambda 表达式

参考:http://c.biancheng.net/view/3741.html

lambda 来源于函数式编程的概念,也是现代编程语言的一个特点。C++11 终于把 lambda 加入了进来。

lambda表达式有如下优点:

  • 声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象。以更直接的方式去写程序,好的可读性和可维护性。
  • 简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和功能分散,让开发者更加集中精力在手边的问题,同时也获取了更高的生产率。
  • 在需要的时间和地点实现功能闭包,使程序更灵活。

lambda 表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。lambda 表达式的语法形式可简单归纳如下:

[ capture ] ( params ) opt -> ret {
    
     body; };

其中

  • capture 是捕获列表,空表示不捕获任何变量;&表示捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获);=表示捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获);=,&foo表示按值捕获外部作用域中所有变量,并按引用捕获 foo 变量。bar按值捕获 bar 变量,同时不捕获其他变量;this表示捕获当前类中的 this 指针,让 lambda 表达式拥有和当前类成员函数同样的访问权限。如果已经使用了 & 或者 =,就默认添加此选项。捕获 this 的目的是可以在 lamda 中使用当前类的成员函数和成员变量。
  • params 是参数表,
  • opt 是函数选项,
  • ret 是返回值类型,
  • body是函数体

猜你喜欢

转载自blog.csdn.net/Gou_Hailong/article/details/127860552