——1.5Policies和Policy Classes
关于template技术:
template <class T>
class Policy
{
};
template <class CreatePolicy>
class WidgetManager :public CreatePolicy
{
};
typedef Policy<Widget> WidgetPolicy;
typedef WidgetManager<WidgetPolicy> MyWidgetMgr;
这并不涉及template template技术,即使你把代码写成这样:
typedef WidgetManager< Policy<Widget> > MyWidgetMgr;
这都只是模板,不管又多少嵌套,编译器都可以聪明的逐一替换。
但是对于下面的代码
typedef WidgetManager< Policy > MyWidgetMgr;
它却可能有别的解释,如果声明是这样的话:
template <template <class Created> class CreatePolicy>
class WidgetManager : public Policy<Widget>
{
};
如你所见,WidgetManager使用了template template,也如你所知道的,这里也存在简化模式,因为有些东西(Created)根本没有用:
template <template <class> class CreatePolicy>
class WidgetManager : public Policy<Widget>
{
};
这本没有太多的悬念,但是Andrei在这里所说的“这种情况下还要求使用者把Widget类型传给OpNewCreator就显得多余而且危险”,其实他是这个意思:
这种情况下你可以使用模板,模板当然每次都要传入类型Widget,但是如果OpNewCreator必须使用参数Widget的时候才有意义的时候,还是使用模板的话,使用者可能在实际使用中传入非法类型,所以这是危险的。如果使用OpNewCreator,它必接受Widget作为参数,这个时候你还是要求传入Widget,就是多余的了。
只要使用模板,这种情况将一直存在,但是如果使用template template,这个参数就不用露面了,而且也可以避免掉被误用的可能性。说到这里应该比较明白了,Andrei这样说是为了引入template template,但是因为这个东西他一直在提,所以看到这里大家一般都已经有了概念了,因为你知道的多了,所以这个地方可能会有误解。
ps(未必正确的东西)
还要说明的一点是你要习惯typedef的使用,这不仅仅是为了方便阅读和使用,而是因为使用typdef的时候,编译器会把模板推导出来。看如下的代码:
WidgetManager< Policy >* pMyWM = new WidgetManager<Policy>;
如果编译器抱怨说它找不到WidgetManager<Policy>的定义,那你可以考虑使用typedef试试能不能改善。这个问题是在我以前的使用把指针声明放在单件里的时候出的问题,当时忙着做其他的东西,这个原因没有具体查找。