C++lambda

C++lambda的语义变化

C++lambda的基本形式

[capture] (parameters) mutable ->return-type {statement}

[capture] :捕捉列表。捕捉列表总是作为lambda的开始,即出现于lambda的开始处。它是lambda的引出符(即开始标志)。编译器可以根据该“标志”来作出判断出该函数是否为lambda函数。同时“捕捉列表”能够捕捉上下文中的变量以作为lambda函数使用。

(parameters):参数列表。和C/C++中的普通函数参数意义一样。该部分是可选的,意味着如果我们不需要进行参数传递时,可以连同括号“()”一起省略掉。

mutable:该关键字为一个修饰符。在默认的情况下,lambda函数总是返回一个const,而当我们在参数列表后面注明了“mutable”关键字之后,则可以取消其常量性质。若在lambda中使用了mutable修饰符,则“参数列表”是不可省略掉的(即使是参数为空)。

->return-type: 函数的返回值类型。和C/C++中的普通函数返回值类型的性质一样。主要目的是用来追踪lambda函数(有返回值情况下)的返回类型。若lambda函数不需要返回值,则可以直接将这部分省略掉。

{statement}:函数体。在该函数体中,除了可以使用参数列表中的变量外,还可以使用所有捕获到的变量(即[capture] 中的变量)。

C++lambda的基本用法

    int a = 3;
    int b = 5;
    std::cout << " not join in lambda : " << "a Address is : " << &a << "\n"\
        << "b address is : " << &b << "\n"\
        <<std::endl;
    
    // 按值来捕获
    auto func1 = [a] {
         std::cout << "func1 is :" << "a Address is : " << &a<<std::endl;
         };
    func1();

    // 按值来捕获
    auto func2 = [=] { 
        std::cout
        << "func2 is :"
        << "a Address is : " << &a << "\n"
        << "b Address is : " << &b << "\n"
        << std::endl; };
    func2();

    // 按引用来捕获
    auto func3 = [&a] { 
        a += 1;
        std::cout <<"func3 is : " << " a Address is : " << &a 
        << std::endl;
        };
    func3();

    // 按引用来捕获
    auto func4 = [&] {
        std::cout <<"func4 is : " << " a Address is : " << &a << "\n"
        << "b Adress is : " <<  &b << "\n"
        << std::endl;
        };
    func4();
not join in lambda : a Address is : 0x60fdec
b address is : 0x60fdf0

func1 is :a Address is : 0x60fdf4
func2 is :a Address is : 0x60fdf8
b Address is : 0x60fdfc

func3 is :  a Address is : 0x60fdec
func4 is :  a Address is : 0x60fdec
b Adress is : 0x60fdf0

C++lambda不能修改捕获值

    int b = 0;
    int * a = &b;
    std::cout << "the a address is : " << *a <<std::endl;
    auto t = [=]() {
        int c = 5;
        a = &c;
        b = 3;
        std::cout << "the a value is :" << *a << b << std::endl;
//        std::cout <<"the a address is :" << a <<std::endl;
    };
    t();
    std::cout << "the a is : "<< *a << std::endl;
main.cpp:99:11: error: cannot assign to a variable captured by copy in a non-mutable lambda

C++关键字mutable改变值

    int b = 0;
    int * a = &b;
    std::cout << "the a value is : " << *a <<std::endl;
    auto t = [=]() mutable {
        int c = 5;
        a = &c;
        b = 3;
        std::cout << "the a value is :" << *a << b << std::endl;
//        std::cout <<"the a address is :" << a <<std::endl;
    };
    t();
    std::cout << "the a is : "<< *a << std::endl;
the a value is : 0
the a value is :53
the a is : 0

C++ 11 功能:

不使lambda的情况

class mycomp2 {
public:
    bool operator() (int i, int j) {
        return (i > j);
    }
};

void test008(){
    std::vector<int> data = {1,23,2,33,2,333};

    std::sort(data.begin(), data.end(), mycomp2());

    for(auto a : data){
        std::cout << a << "  ";
    }
}
```C++
333  33  23  2  2  1 

C++11 lambda在算法中的应用

std::vector<int> data = {1,23,2,33,2,333};
int cnt = std::count_if(std::cbegin(data),std::cend(data),[](auto it){return it>3;});
std::sort(data.begin(),data.end(),[](auto a, auto b){return a > b;});
std::for_each(std::cbegin(data), std::cend(data), [](auto val){std::cout <<" " <<val ;});
std::cout << "the more 3 of data is : " << cnt << std::endl;

the grater 3 of data is : 3
 333 33 23 2 2

C++14功能:

增加捕获新的变量

    int a = 3;
    int b = 5;
    auto f = [&, M = 5](auto c, auto d){
        std::cout << "M is : "<< M << std::endl;
        return a + b + M + c + d;
    };
    std::cout << f(3.145, 6) << std::endl;

使用auto修饰输入参数

[](auto a , auto b){}
    auto f = [](auto a, auto b){
        return a + b;
    };
    std::cout << f(1,2) << std::endl;
    std::cout << f(1.2,2.4)   <<std::endl;
3
3.6

C++17

通过*this, 进行值传递的方式

class A{
public:
    A(){}
    ~A(){}
    void test(){
        auto f = [*this]() mutable {
             std::sort(this->a.begin(), this->a.end(),[](auto a, auto b){return a > b;});
             std::for_each(std::cbegin(this->a), std::cend(this->a), [](auto val){std::cout <<" " <<val ;});
             std::cout << std::endl;
    };
        f();
        std::for_each(std::cbegin(this->a), std::cend(this->a), [](auto val){std::cout <<" " <<val ;});
    }

private:
    std::vector<int> a = {1,23,2,33,2,333};
};
void test010(){
    A a;
    a.test();
}
 333 33 23 2 2 1
 1 23 2 33 2 333

C++闭包

面向过程的写法

int frame_rate = 11025;
//面向过程的写法
double frequency = 261.63;
double amplitude = 0.3;
double getData(double t);


void test002(){
    WavWapper ww;
    ww.CreateWavFile("sound.wav", 1, frame_rate, 2);
    for(int i = 0; i < 10000; ++i){
        unsigned char cache = 16384 * getData(i);
        ww.WriteToFile(&cache, 1);
    }
    ww.CloseFile();
}
double getData(double t){
    int period = frame_rate / amplitude;
    double saw_wave = t /period - floor(t / period + 0.5);
    double tri_wave = 2 * abs(2 * saw_wave) - 1;
    return amplitude * tri_wave;
}
-0.3
-0.299967
-0.299935
-0.299902
-0.299869
-0.299837
-0.299804
-0.299771
-0.299739
-0.299706
-0.299673
-0.299641
-0.299608
-0.299576
-0.299543
-0.29951
-0.299478
-0.299445
-0.299412
-0.29938
-0.299347
-0.299314
-0.299282
-0.299249
-0.299216
-0.299184
-0.299151
-0.299118
-0.299086
-0.299053
-0.29902
-0.298988
-0.298955
-0.298922
-0.29889
-0.298857
-0.298824
-0.298792
-0.298759
-0.298727
-0.298694
-0.298661
-0.298629
-0.298596
-0.298563
-0.298531
-0.298498
-0.298465
-0.298433
-0.2984
-0.298367
-0.298335
-0.298302
-0.298269
-0.298237
-0.298204
-0.298171
-0.298139
-0.298106
-0.298073
-0.298041
-0.298008
-0.297976
-0.297943
-0.29791
-0.297878
-0.297845
-0.297812
-0.29778
-0.297747
-0.297714
-0.297682
-0.297649
-0.297616
-0.297584
-0.297551
-0.297518
-0.297486
-0.297453
-0.29742
-0.297388
-0.297355
-0.297322
-0.29729
-0.297257
-0.297224
-0.297192
-0.297159
-0.297127
-0.297094
-0.297061
-0.297029
-0.296996
-0.296963
-0.296931
-0.296898
-0.296865
-0.296833
-0.2968
-0.296767

闭包的写法

void test001(){
    WavWapper ww;
    ww.CreateWavFile("sound.wav", 1, frame_rate, 2);

    auto tri = [](auto frequency, auto amplitude){
        int period = (frame_rate / frequency);
        auto sampler = [=](auto t){
            double saw_wave = (double)t / (double)period - floor((double)t / (double)period + 0.5)  ;
            double tri_wave = 2 * abs(2 * saw_wave) - 1;
            return amplitude * tri_wave;
        };
        return sampler;
    };

    auto c =tri(261.63, 0.3);
    for(int i = 0; i < 10000; ++i){
        std::cout << c(i) << std::endl;
        unsigned char cache = 16384 * c(i);
        ww.WriteToFile(&cache, 1);
    }
    ww.CloseFile();
}
-0.3
-0.271429
-0.242857
-0.214286
-0.185714
-0.157143
-0.128571
-0.1
-0.0714286
-0.0428571
-0.0142857
0.0142857
0.0428571
0.0714286
0.1
0.128571
0.157143
0.185714
0.214286
0.242857
0.271429
0.3
0.271429
0.242857
0.214286
0.185714
0.157143
0.128571
0.1
0.0714286
0.0428571
0.0142857
-0.0142857
-0.0428571
-0.0714286
-0.1
-0.128571
-0.157143
-0.185714
-0.214286
-0.242857
-0.271429
-0.3
-0.271429
-0.242857
-0.214286
-0.185714
-0.157143
-0.128571
-0.1
-0.0714286
-0.0428571
-0.0142857
0.0142857
0.0428571
0.0714286
0.1
0.128571
0.157143
0.185714
0.214286
0.242857
0.271429
0.3
0.271429
0.242857
0.214286
0.185714
0.157143
0.128571
0.1
0.0714286
0.0428571
0.0142857
-0.0142857
-0.0428571
-0.0714286
-0.1
-0.128571
-0.157143
-0.185714
-0.214286
-0.242857
-0.271429
-0.3
-0.271429
-0.242857
-0.214286
-0.185714
-0.157143
-0.128571
-0.1
-0.0714286
-0.0428571
-0.0142857
0.0142857
0.0428571
0.0714286
0.1
0.128571
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值