仿函数与lambda

2021-12-10  本文已影响0人  404Not_Found

仿函数

其实就是重载 ( )
示例代码

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

using namespace  std;

class Compare
{
public:
    bool operator() (int a, int b) {
        return a > b;
    }
};

int main() {
    vector<int> vi = {1,3,5,6,7,9,2,4,5,6,8,10};
    //可以把对象当函数用
    sort(vi.begin(), vi.end(), Compare());
    for(auto & i:vi) {
        cout << i <<endl;
    }
    return 0;
}

相当于把对象当作函数来用。

Compare C;
//sort 的 元素会往operator里塞
C.operator() (int a, int b);

为什么需要仿函数

可以携带更多的状态

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

using namespace  std;

class Compare
{
public:
    Compare(bool f = true):flag(f) {}
    bool operator() (int a, int b) {
        if(flag == true)
            return a > b;
        else
            return a < b;
    }

protected:
    bool flag;
};

int main() {
    vector<int> vi = {1,3,5,6,7,9,2,4,5,6,8,10};
    sort(vi.begin(), vi.end(), Compare(false));
    for(auto & i:vi) {
        cout << i <<endl;
    }
    return 0;
}

核心相当于:

//Compare(false) 可以化身为:
Compare C(false);
C.operator()(int a, intb);

非常明显: 可以携带更多的状态.

Lambda 表达式

结构如下:

[capture lists](parameterlist) mutable -> return type {function body}
int main(int argc, char *argv[])
{
  //让 auto 自己去推导
    auto foo = []{return 1+2;};
    cout<<foo()<<endl;
    cout<<[]{return 1+2;}()<<endl;
    return 0;
}
int main(int argc, char **argv)
{
    auto foo = [](int x, int y){return x+y;};
    //可带默认参数S
    auto foo1 = [](int x = 10, int y = 20){return x+y;};

    //返回值,一般不会写,自动推导就行j了
    auto foo2 = [](int x = 10, int y= 30) ->int {return x + y;};


    cout<<foo(1,2)<<endl;
    cout<<foo1()<<endl;
    cout<<foo2(40, 50)<<endl;
    return 0;
}

[ ] 闭包 与 mutable

[capture list] 闭包的含义 就是与外界无法构成联系

int main(int argc, char **argv) {
  int x = 100, y = 200;
  auto f = [ ]() {
      x = 50;
      y= 100;
  };
}

上述代码会报错,报 无法抓取 x 与 y, 说明 [ ] 对 x 和 y 都没抓到。

int main(int argc, char**argv) {
    int x = 100, y= 200;
    //加上& 是可以的,说明 闭包里面的东西可以勾到外面的了
    //引用
    auto f = [&]() {
        x = 50;
        y = 100;
    };

    f();
    cout<<x<<":"<<y<<endl;
}

以引用的方式 抓取了 x, y 并可以在lambda 中修改x, y 的值

    //= 复制,产生复本
    auto g= [=]{
        x = 50;
        y = 50;
    };

首先 以 [=] 的意义是 全部抓取变量,并以复制的方式传进来,但只能读,但不能写

 /*里边变了,外面没j变*/
    //= 复制,产生复本
    auto g= [=]()mutable{
        x = 50;
        y = 50;
    };
int x = 100;
int *p = &x;
auto func = [p]() {
    *p = *p +1; //不i会报错
}

x ,y 以副本方式传进来,可以修改,但并不影响 外界 x, y 的值。

=mutable 杀伤力太大

/*需求:=杀伤力太大,勾连所有变量,我只想要x*/
    //x 复制,&x x引用,修改了x的值, y,是 复本传递
    auto h = [&x,y]()mutable{
       int sum = 0;
       sum += x;
       x +=100;
    };
闭包.png
int main(int argc, char **argv) {
    vector<int>  vi = {1,2,3,4,5,6};

    for_each(vi.begin(), vi.end(), [](int &i) {
        cout<<i<<endl;
    });

    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读