栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

函数对象与lambda表达式

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

函数对象与lambda表达式

C++11 函数对象的升级版 ==》lambda表达式。

函数对象的用处:
  • 使用在泛型算法参数传递,比如排序算法中自定义比较方式、
  • 有顺序的数据结构,自定义操作,比如优先级队列、
  • 智能指针的释放,可以自定义操作。
函数对象的缺点:

        一般不会单独使用函数对象。使用时候需要定义一个类,很多时候没有必要,因为要用函数对象,然后定义一个类,只使用一次,这个类就一直存在代码处。

lambda表达式语法:
[捕获外部变量](参数列表)->返回值{函数体};
简单例子:
struct cmp{
    int operator()(int a, int b) {
        return a+b;
    }
};

cmp()(10,10);


[](int a, int b){return a+b;}(10,10);

//如果lambda表达式返回值类型很简单就可以编译出来,
可以不写->返回值

从上面可以看出来,
lambda表达式中参数列表就是函数对象重载()中参数,
             返回值                  的返回值,
             函数体                  的函数体

lambda表达式捕获值:

lambda 表达式中,捕获外部变量

[]   不捕获变量
[&]  以引用的方式捕获所有外部变量
[=]  以值的方式捕获外部所有变量
[this]  捕获当前类中的this 指针,如果已经使用了 & 或者 =, 默认添加此选项
[bar]  按值捕获 bar 变量,同时不捕获其他变量
[&bar]  按引用捕获 bar 变量,同时不捕获其他变量
auto func = [a, b](){
    int tmp = a;
    a = b;
    b = tmp;
};

上面的lambda表达式,转换成函数对象是下面的样子

编译器一般把只读方法,都修饰成const。
struct Test{
    Test(int a, int b) : ma(a), mb(b){}
    void operator()() const {
        int tmp = a;
        a = b;
        b = tmp;
    }
private:
    int ma;
    int mb;
};


int a = 10;
int b = 9;
func();

Test test(a,b);
test();
显然上面两种方法都有语法错误,无法修改通过值传递的参数。

改变成按引用传递即可。

在上面这段代码中,想修改const,可以在变量前加 mutable 修饰。

在上面有一个问题,如果改成了引用传递,为什么可以改变?函数对象 operator() 不是还是由const 修饰吗?

struct Test{
    Test(int a, int b) : ma(a), mb(b){}
    void operator()() const {
        int tmp = a;
        a = b;
        b = tmp;
    }
private:
    int& ma;
    int& mb;
};

并不是改变这两个引用变量本身,
引用底层还是指针,
这四个字节的指针并没有改变,
改变的是指针所指向的内容。

lambda的使用

lambda 只能使用在语句中,如果想要跨语句使用之前定义好的的lambda表达式,该如何做?用什么类型来表示lambda表达式?

lambda 表达式==》函数对象。用function类型

用function对象,表示lambda表达式。

例子一:
map> caculateMap;
caculateMap[0] = [](int a, int b)->int {return a+b;};
caculateMap[1] = [](int a, int b)->int {return a-b;};
.....


例子二:
在智能指针中,如果打开了一个文件,那么对于这个文件指针的delete操作,需要自定义,fclose(FILE*)
unique_ptr 
    ptr(open("data.txt","r"),[](FILE* p)->void{fclose(p);});

例子三:
优先级队列的自定义排序规则

struct Date{
    int ma;
    int mb;
};
priority_queue
             , function> priQue([](Date& a, Date& b)->bool
                                                    {
                                                        return a.ma > b.ma;
                                                     }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/929145.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号