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; } |