2014-11-06 星期四 21:54:23
隨便記錄,本文是loki command模式的簡化版本。雖然是簡化的,但是泛化的精髓還是原汁原味的。我們在泛化編程時,對模板形參可以用具現的眼光來看待。泛化編程,具現理解。
1、代碼(.h)
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
|
#include
<algorithm> #include
<iostream> #include
<vector> #include
<iterator> #include
<map> #include
<memory> #include
<typeinfo> #include
<assert.h> #include
<stdio.h> #ifndef
__MYFUNCTOR_H__ #define
__MYFUNCTOR_H__ class NullType
{}; template < class T, class U> struct Typelist { typedef T
Head; typedef U
Tail; }; #define
TYPELIST_1(T1) Typelist<T1, NullType> #define
TYPELIST_2(T1, T2) Typelist<T1, TYPELIST_1(T2) > #define
TYPELIST_3(T1, T2, T3) Typelist<T1, TYPELIST_2(T2, T3) > //////////////////////////////////////////////////////////////////////////////// //
class template TypeAtNonStrict //
Finds the type at a given index in a typelist //
Invocations (TList is a typelist and index is a compile-time integral //
constant): //
a) TypeAt<TList, index>::Result //
returns the type in position 'index' in TList, or NullType if index is //
out-of-bounds //
b) TypeAt<TList, index, D>::Result //
returns the type in position 'index' in TList, or D if index is out-of-bounds //////////////////////////////////////////////////////////////////////////////// template < class TList,
unsigned int index, typename DefaultType
= NullType> struct TypeAtNonStrict { typedef DefaultType
Result; }; template < class Head, class Tail, typename DefaultType> struct TypeAtNonStrict<Typelist<Head,
Tail>, 0, DefaultType> { typedef Head
Result; }; template < class Head, class Tail,
unsigned int i, typename DefaultType> struct TypeAtNonStrict<Typelist<Head,
Tail>, i, DefaultType> { typedef typename TypeAtNonStrict<Tail,
i - 1, DefaultType>::Result Result; }; template < typename R, class TList> class FunctorImpl; template < typename R> class FunctorImpl<R,
NullType> { public : typedef R
ResultType; virtual ResultType
operator()() = 0; virtual FunctorImpl
*Clone() const =
0; virtual ~FunctorImpl(){} }; template < typename R, typename P1> class FunctorImpl<R,
TYPELIST_1(P1) > { public : typedef R
ResultType; //typedef
typename TypeTraits<P1>::ParameterType Parm1; typedef P1
Parm1; virtual ResultType
operator()(Parm1) = 0; virtual FunctorImpl
*Clone() const =
0; virtual ~FunctorImpl(){} }; template < typename R, typename P1, typename P2> class FunctorImpl<R,
TYPELIST_2(P1, P2) > { public : typedef R
ResultType; typedef P1
Parm1; typedef P2
Parm2; FunctorImpl() { printf ( "line
%d, FunctorImpl::%s\n" ,
__LINE__, __func__); } virtual ResultType
operator()(Parm1, Parm2) = 0; virtual FunctorImpl
*Clone() const =
0; virtual ~FunctorImpl(){} }; template < class ParentFunctor, typename Fun> class FunctorHandler #if
0 : public FunctorImpl < typename ParentFunctor::ResultType, typename ParentFunctor::ParamList > #else : public ParentFunctor::Impl #endif { public : typedef typename ParentFunctor::Parm1
Parm1; typedef typename ParentFunctor::Parm2
Parm2; typedef typename ParentFunctor::ResultType
ResultType; FunctorHandler( const Fun&
fun):fun_(fun) { printf ( "line
%d, FunctorHandler::%s\n" ,
__LINE__, __func__); } FunctorHandler
*Clone() const { return new FunctorHandler(* this ); } ResultType
operator()(Parm1 p1) { return fun_(p1); } ResultType
operator()(Parm1 p1, Parm2 p2) { printf ( "line
%d, FunctorHandler::%s\n" ,
__LINE__, __func__); return fun_(p1,
p2); } private : Fun
fun_; }; //Functor template < typename R, class TList> class Functor; #define
IMPL_IN_CLASS template < typename R, class TList> class Functor { public : typedef R
ResultType; typedef TList
ParamList; //
Handy type definitions for the body type typedef FunctorImpl<R,
TList> Impl; //typedef
typename Impl::Parm1 Parm1; //typedef
typename Impl::Parm2 Parm2; typedef typename TypeAtNonStrict<TList,
0, NullType>::Result Parm1; typedef typename TypeAtNonStrict<TList,
1, NullType>::Result Parm2; public : Functor()
: spImpl_(0) { printf ( "line
%d, Functor::%s, num %d\n" ,
__LINE__, __func__, 2); } Functor( const Functor&
rhs) : spImpl_(Impl::Clone()) {} explicit Functor(std::auto_ptr<Impl>
spImpl) : spImpl_(spImpl) {} Functor&
operator=( const Functor&); #ifdef
IMPL_IN_CLASS template < typename Fun> Functor( const Fun&
fun) :spImpl_( new FunctorHandler<Functor,
Fun>(fun)) { printf ( "line
%d, Functor::%s\n" ,
__LINE__, __func__); } #else template < class Fun> Functor( const Fun&
fun); #endif private : public : //
operator() implementations for up to 2 arguments ResultType
operator()() const { return (*spImpl_)(); } ResultType
operator()(Parm1 p1) const { return (*spImpl_)(p1); } ResultType
operator()(Parm1 p1, Parm2 p2) const { printf ( "line
%d, Functor::%s\n" ,
__LINE__, __func__); return (*spImpl_)(p1,
p2); } private : std::auto_ptr<Impl>
spImpl_; }; #endif |
2、代碼(.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
|
#include
"myfunctor.h" #ifndef
IMPL_IN_CLASS //位於class本體之外的member
template定義式 //第一組template<typename
R, class Tlist>用於class template Functor //第二組template<class
Fun>用於構造函數的參數 template < typename R, class Tlist> template < typename Fun> Functor<R,
Tlist>::Functor( const Fun&
fun) :spImpl_( new FunctorHandler<Functor,
Fun>(fun)) { printf ( "line
%d, Functor::%s, num %d\n" ,
__LINE__, __func__, 2); } #endif struct TestFunctor { void operator()( int p1, double p2) { printf ( "TestFunctor::operator(%d,
%f) called\n" ,
p1, p2); } }; int main( int argc, char *
argv[]) { TestFunctor
f; #if
0 Functor< double ,
TYPELIST_2( int , double )
> myFunctor; double result
= myFunctor(4, 4.5); #endif Functor< void ,
TYPELIST_2( int , double )
> cmd(f); cmd(5,
5.5); //error,operator()
is not invalid because FunctorImpl< double, TYPELIST_2(int , double) > //dose
not define one //double
result1 = myFunctor(); return 0; } |