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