在C++中不直接支持约束,用过C#模板的有个where来处理,但是C++中也有些小的技巧来处理。
在不完美C++中的must_have_base如下:
template<typename D, typename B>
struct must_have_base
{
~must_have_base()
{
void (*p)(D*, B*) = constraints;
}
private:
static void constraints(D *pd, B *pb)
{
pb = pd;
}
};
原理是通过不执行的成员函数把函数指针在析构函数中赋值,强迫编译器在编译期间检查成员函数内的约束。
自己写了个小的实例,虽然这儿有点点牵强,但是,很多情况也需要检查是否是某种类型的子类型的时候还是可以的,
完整代码如下:
1
2 template<typename D, typename B>
3 struct must_have_base
4 {
5 ~must_have_base()
6 {
7 void (*p)(D*, B*) = constraints;
8 }
9
10 private:
11 static void constraints(D *pd, B *pb)
12 {
13 pb = pd;
14 }
15 };
16
17 class base
18 {
19 public:
20 virtual ~base() {}
21
22 virtual void run() = 0;
23 };
24
25 class inherit_base: public base
26 {
27 public:
28 virtual void run()
29 {
30
31 }
32 };
33
34 class inherit_not_base
35 {
36 public:
37 virtual void run()
38 {
39
40 }
41 };
42
43 class test
44 {
45 public:
46 template<typename T>
47 void testfunc(T &t)
48 {
49 must_have_base<T, base>();
50
51 t.run();
52 }
53 };
54
55 int main()
56 {
57 test t_ok, t_nok;
58 inherit_base hb;
59 inherit_not_base hnb;
60 t_ok.testfunc(hb);
61 t_nok.testfunc(hnb);
62
63 return 0;
64 }
抛砖引玉,希望这些东西都能用在实际的工程代码中。