-
Notifications
You must be signed in to change notification settings - Fork 1
/
item34_prefer_lambda_to_bind.cpp
90 lines (78 loc) · 2.9 KB
/
item34_prefer_lambda_to_bind.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
#include <iostream>
#include "type_name.hpp"
#include <chrono>
#include <functional>
using namespace std;
/* typedef for a point in time */
using Time = std::chrono::steady_clock::time_point;
enum class Sound{Beep, Siren, Whistle};
// typedef for a length of time
using Duration = std::chrono::steady_clock::duration;
/* At time t, make sound s for duration d */
void setAlarm(Time t, Sound s, Duration d){
cout << "hello, world \n";
};
enum class Volumn{Normal, Loud, LoudPlusPlus};
/* overloaded setAlarm*/
void setAlarm(Time t, Sound s, Duration d, Volumn v){
cout<< "HELLO, WORLD \n";
}
class PolyWidget{
public:
template<typename T>
void operator() (const T& param){
cout << param << endl;
}
template<typename T>
void operator() (const T& param) const{
cout << param << endl;
}
};
int main(){
/* In lambda version, the steady_clock::now() + 1h is an argument to setAlarm
It will be evaluated when setAlarm is called.
*/
auto setSoundL = [](Sound s){
using namespace std::chrono;
setAlarm(steady_clock::now() + hours(1), s , seconds(30));
};
setSoundL(Sound::Beep);
/* Use std::bind version */
using namespace std::chrono;
using namespace std::literals;
using namespace std::placeholders;
/* In std::bind() version, steady_clock::now+1h is passed to std::bind, not to setAlarm.
Which means that the time resulting from the expression will be evaluated when the std::bind
is called, and the time resulting from the expression will be stored inside the resulting bind
object.
*/
/* Fix overloaded function */
using SetAlarm3ParamType = void(*)(Time t, Sound s, Duration d);
auto setSoundB = std::bind(static_cast<SetAlarm3ParamType>(setAlarm), steady_clock::now() + 1h, _1, 30s);
/* Fix bug above */
auto SetSoundB1 =std::bind(static_cast<SetAlarm3ParamType>(setAlarm), std::bind(std::plus<steady_clock::time_point>(), steady_clock::now(), 1h), _1, 30s);
int lowVal = 1, highVal = 10;
auto betweenL = [lowVal, highVal](const auto& val){
return lowVal <= val && val <= highVal;
};
cout << "5 is between 1 and 10 : " << betweenL(5) << endl;
/* bind version c++11 version*/
auto betweenB = std::bind(std::logical_and<>(), std::bind(std::less_equal<int>(), lowVal, _1),
std::bind(std::less_equal<int>(), _1, highVal));
cout << "5 is between 1 and 10 (bind version) :" << betweenB(5) << endl;
PolyWidget pw;
/* bind version */
auto boundPW = std::bind(pw, _1);
boundPW(2);
/* Codes in book have bug */
auto boundPWL = [pw](const auto& param)->void // C++14
{ pw(param); };
boundPWL(3);
//boundPWL(3);
//int x = 3;
//boundPWL(&x);
//const PolyWidget pw1;
/* c++14 version lambda */
// auto boundPWL = [pw](const auto& param){pw(param);};
// boundPWL(3);
}