C++针对一个类的子类进行特化
在水木C++版,有人提出如何针对"基类是xx类的类型"进行特化。这里面的关键
是理解这样几件事情:
1. 模板的特化
2. 如何在编译期判断xx是xx的基类
我们使用了这样一个type traits:
1
2 template <typename B, typename D>
3 struct is_base_of // check if B is a base of D
4 {
5 typedef char yes[1];
6 typedef char no[2];
7
8 static yes& test(B*);
9 static no& test( );
10
11 static D* get(void);
12
13 static const bool value = sizeof(test(get())) == sizeof(yes);
14 };
15
关键是理解struct is_base_of的最后一行,涉及对sizeof的理解:
The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is an unevaluated operand (Clause 5), or a parenthesized
type-id.
--- Working Draft, Standard for Programming Language C++ (5.3.3)
重点就是test(get())是unevaluated,编译期可以推断出该表达式的类型,如果
D是B的子类,则`static yes& test(B*);`是更好的匹配,否则就是另一个,而
它们返回值类型的大小不一样,藉此可以判断D是否B的子类。
下面是模板类的代码:
1
2 struct Base
3 {
4 };
5
6 template <typename T, bool nouse=is_base_of<Base, T>::value>
7 class ATemplate
8 {
9 public:
10 ATemplate( )
11 {
12 printf( "no\n" );
13 }
14 ~ATemplate( )
15 {
16
17 }
18 };
19
20
21 template <typename T>
22 class ATemplate<T,true>
23 {
24 public:
25 ATemplate( )
26 {
27 printf( "yes\n" );
28 }
29 ~ATemplate( )
30 {
31
32 }
33 };
34
35 struct D:public Base
36 {
37
38 };
39 struct C
40 {
41
42 };
43
44
45 int main( )
46 {
47 ATemplate<C> t;
48 ATemplate<D> t1;
49 return 0;
50 }
51
结果如下:
$ ./t
no
yes
摘自 卡列宁的微笑
补充:软件开发 , C++ ,