• C++ 在函数中定义函数


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

    Part.I 实例

    下面是一个简单的样例,其中在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;
    }
    
    • 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

    结果输出为:

    ----------Origin---------
    1 2
    2 1
    3 6
    ----------After Sorted---------
    3 6
    1 2
    2 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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; };
    
    • 1

    其中

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

  • 相关阅读:
    在MongoDB的对象中插入数组详解
    如何用 Zabbix 监控 Radius 服务?
    2023天津公租房网上登记流程图,注册到信息填写
    Java读源码之Netty深入剖析
    golang 面试
    1.Zookeeper理论基础
    【CGAL_网格】Surface_mesh
    day37
    事务的隔离级别
    OJ:循环队列
  • 原文地址:https://blog.csdn.net/Gou_Hailong/article/details/127860552