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