-
Notifications
You must be signed in to change notification settings - Fork 0
/
29.lambda.cpp
378 lines (322 loc) · 7.75 KB
/
29.lambda.cpp
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
//
// Created by satellite on 2023-05-21.
//
//lambda
//#define code_7_17
//#define code_7_22
//#define code_7_23
//#define code_7_24
//#define code_7_25
//#define code_7_26
//#define code_7_27
//#define code_7_29
//#define code_7_30
//#define code_7_31
//#define code_7_32
//#define code_7_33
//#define code_7_34
#define code_7_35
#ifdef code_7_17
int main(){
int girls=3,boys=4;
auto totalChild=[](int x,int y)->int{return x+y;};
return totalChild(girls,boys);
}
#endif
//[capture](parameters)mutable->return_type{statement}
/*mutable:mutable修饰符。默认情况下,lambda函数总是一个const函
数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省
略(即使参数为空)。
而在块作用域中的lambda函数仅能捕捉父作用
域中的自动变量,捕捉任何非此作用域或者是非自动变量(如静态变
量等)都会导致编译器报错。
*/
#ifdef code_7_22
class AirportPrice {
private:
float dutyfreerate;
public:
AirportPrice(float rate) : dutyfreerate(rate) {}
float operator()(float price) {
return price * (1 - dutyfreerate / 100);
}
};
int main() {
float tax_rate = 5.5f;
AirportPrice Changi(tax_rate);
auto Changi2 =
[tax_rate](float price) -> float
{ return price * (1 - tax_rate / 100); };
float purchased = Changi(3699);
float purchased2 = Changi2(2899);
}
#endif
#ifdef code_7_23
extern int z;
extern float c;
void Calc(int&,int,float&,float);
void TestCalc(){
int x,y=3;
float a,b=4.0;
int success=0;
auto validate=[&]()->bool
{
if((x==y+z)&&(a==b+c))
return 1;
else
return 0;
};
Calc(x,y,a,b);
success+=validate();
y=1024;
b=1e13;
Calc(x,y,a,b);
success+=validate();
}
#endif
#ifdef code_7_24
int Prioritize(int);
int AllWorks(int times) {
int i;
int x;
try {
for (i = 0; i < times; i++)
x += Prioritize(i);
}
catch (...) {
x = 0;
}
const int y = [=] {
int i, val;
try {
for (i = 0; i < times; i++)
val += Prioritize(i);
}
catch (...) {
val = 0;
}
return val;
}();
}
#endif
#ifdef code_7_25
#include <iostream>
using namespace std;
int main(){
int j=12;
auto by_val_lambda=[=]{return j+1;};
auto by_ref_lambda=[&]{return j+1;};
cout<<"by_val_lambda:"<<by_val_lambda()<<endl;
cout<<"by_ref_lambda:"<<by_ref_lambda()<<endl;
j++;
cout<<"by_val_lambda:"<<by_val_lambda()<<endl;
cout<<"by_ref_lambda:"<<by_ref_lambda()<<endl;
}
#endif
/*每个lambda表达式则会产生一个闭包类型的
临时对象(右值)。因此,严格地讲,lambda函数并非函数指针。不
过C++11标准却允许lambda表达是向函数指针的转换,但前提是
lambda函数没有捕捉任何变量,且函数指针所示的函数原型,必须跟
lambda函数有着相同的调用方式。*/
#ifdef code_7_26
int main() {
int girls = 3, boys = 4;
auto totalChild = [](int x, int y) -> int { return x + y; };
typedef int(*allChild)(int x, int y);
typedef int(*oneChild)(int x);
allChild p;
p = totalChild;
oneChild q;
//q = totalChild;//编译失败,参数必须一致
decltype(totalChild) allPeople = totalChild;//需通过decltype获得lambda的类型
decltype(totalChild) totalPeople = p;//编译失败,指针无法转换为lambda
return 0;
}
#endif
#ifdef code_7_27
int main() {
int val;
//编译失败,在const的lambda中修改常量
auto const_val_lambda = [=]() { val = 3; };
//非const的lambda,可以修改常量数据
auto mutable_val_lambda = [=]()mutable { val = 3; };
//依然是const的lambda,不过没有改动引用本身
auto const_ref_lambda = [&] { val = 3; };
//依然是const的lambda,通过参数传递val
auto const_param_lambda = [&](int v) { v = 3; };
const_param_lambda(val);
return 0;
}
//c++11中lambda函数默认是一个const函数
#endif
#ifdef code_7_29
#include <vector>
#include <algorithm>
using namespace std;
vector<int> nums;
vector<int> largeNums;
const int ubound = 10;
inline void LargeNumsFunc(int i) {
if (i > ubound)
largeNums.push_back(i);
}
void Above() {
//传统的for循环
for (auto itr = nums.begin(); itr != nums.end(); ++itr) {
if (*itr >= ubound)
largeNums.push_back(*itr);
}
//使用函数指针
for_each(nums.begin(), nums.end(), LargeNumsFunc);
//使用lambda函数和算法for_each
for_each(nums.begin(), nums.end(), [=](int i) {
if (i > ubound)
largeNums.push_back(i);
});
}
#endif
#ifdef code_7_30
#include <vector>
#include <algorithm>
using namespace std;
vector<int> nums;
vector<int> largeNums;
class LNums {
public:
LNums(int u) : ubound(u) {}
void operator()(int i) const {
if (i > ubound)
largeNums.push_back(i);
}
private:
int ubound;
};
void Above(int ubound) {
//传统的for循环
for (auto itr = nums.begin(); itr != nums.end(); ++itr) {
if (*itr >= ubound)
largeNums.push_back(*itr);
}
//使用仿函数
for_each(nums.begin(), nums.end(), LNums(ubound));
//使用lambda函数和算法for_each
for_each(nums.begin(), nums.end(), [=](int i) {
if (i > ubound)
largeNums.push_back(i);
});
}
#endif
#ifdef code_7_31
#include <vector>
#include <algorithm>
using namespace std;
extern vector<int> nums;
void OneCond(int val) {
//传统的for循环
for (auto i = nums.begin(); i != nums.end(); i++)
if (*i == val)break;
//内置的仿函数(template)equal_to,通过bind2nd使其成为单参数调用的仿函数
find_if(nums.begin(), nums.end(), bind2nd(equal_to<int>(), val));
//使用lambda函数
find_if(nums.begin(), nums.end(), [=](int i) {
return i == val;
});
}
#endif
#ifdef code_7_32
#include <vector>
#include <algorithm>
using namespace std;
extern vector<int> nums;
void TwoCond(int low,int high){
//传统的for循环
for(auto i=nums.begin();i!=nums.end();i++)
if(*i>=low&&*i<high)break;
//利用了3个内置的仿函数,以及非标准的compose2
find_if(nums.begin(),nums.end(),
compose2(logical_and<bool>(),
bind2nd(less<int>(),high),
bind2nd(greater_equal<int>(),low)));
//使用lambda函数
find_if(nums.begin(),nums.end(),[=](int i){
return i>=low&&i<high;
});
}
#endif
#ifdef code_7_33
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<int> nums;
void Add(const int val) {
auto print =[]{
for (auto s: nums) { cout << s << '\t'; }
cout << endl;
};
//传统的for循环方式
for (auto i = nums.begin(); i != nums.end(); ++i) {
*i = *i + val;
}
print();
//试一试for_each及内置仿函数
for_each(nums.begin(), nums.end(), bind2nd(plus<int>(), val));
print();
//实际这里需要使用STL的一个变动性算法:transform
transform(nums.begin(), nums.end(), nums.begin(),
bind2nd(plus<int>(), val));
print();
//不过在lambda的支持下,我们还是可以只使用for_each
for_each(nums.begin(), nums.end(), [=](int&i){
i += val;
});
print();
}
int main() {
for (int i = 0; i < 10; i++) {
nums.push_back(i);
}
Add(10);
return 1;
}
#endif
#ifdef code_7_34
#include <vector>
#include <algorithm>
#include <iostream>
#include <numeric>
using namespace std;
void Stat(vector<int> &v) {
int errors;
int score;
auto print = [&] {
cout << "Errors:" << errors << endl
<< "Score:" << score << endl;
};
//使用accumulate算法,需要两次循环
errors = accumulate(v.begin(), v.end(), 0);
score = accumulate(v.begin(), v.end(), 100, minus<int>());
print();
errors = 0;
score = 100;
//使用lambda则只需要一次循环
for_each(v.begin(), v.end(), [&](int i) {
errors += i;
score -= i;
});
print();
}
int main() {
vector<int> v(10);
generate(v.begin(), v.end(), [] {
return rand() % 10;
});
Stat(v);
}
#endif
#ifdef code_7_35
int d = 0;
int TryCapture(){
auto ill_lambda=[d]{}; //超出捕获列表超出父作用域
}
#endif