-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.cpp
105 lines (86 loc) · 1.86 KB
/
main.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
#include <iostream>
struct Cat
{
void Ruffle() const
{
std::cout << "Purr!" << std::endl;
}
void Stroke() const
{
std::cout << "Pur!" << std::endl;
}
};
template<bool IsConst>
using CatHandler = typename std::conditional_t
<
IsConst
, std::function<void(Cat const*)>
, std::function<void(Cat*)>
>;
template<bool IsConst>
void ruffle(CatHandler<IsConst>&& aHandler)
{
Cat cat;
aHandler(&cat);
}
template<bool IsConst>
void stroke(CatHandler<IsConst>&& aHandler)
{
Cat cat;
aHandler(&cat);
}
struct Tiger
: Cat
{
};
template<bool IsConst>
using TigerHandler = typename std::conditional_t
<
IsConst
, std::function<void(Tiger const*)>
, std::function<void(Tiger*)>
>;
template<bool IsConst>
void ruffle(TigerHandler<IsConst>&& aHandler)
{
Tiger tiger;
aHandler(&tiger);
}
template<bool IsConst>
void stroke(TigerHandler<IsConst>&& aHandler)
{
Tiger tiger;
aHandler(&tiger);
}
void test1()
{
ruffle<true>([](Tiger const* aTiger){ aTiger->Ruffle(); });
// Purr!
// ruffle<true>([&](Tiger* aTiger){ aTiger->Ruffle(); });
// error: no matching function for call to 'ruffle'
ruffle<false>([](Tiger* aTiger){ aTiger->Ruffle(); });
// Purr!
ruffle<false>([](Tiger const* aTiger){ aTiger->Ruffle(); });
// Purr!
}
void test2()
{
// ruffle<true>([](Cat const* aCat) { aCat->Ruffle(); });
// error: call to 'ruffle' is ambiguous
CatHandler<true> handler = [](Cat const* aCat) { aCat->Stroke(); };
stroke<true>(std::move(handler));
// Pur!
stroke<true>(CatHandler<true>( [](Cat const* aCat) { aCat->Stroke(); } ));
// Pur!
stroke<true>(CatHandler<true> {
[](Cat const* aCat) { aCat->Stroke(); }
});
// Pur!
// handler(nullptr);
// 'handler' used after it was moved
}
int main()
{
test2();
return 0;
}