假设 Widget 类定义是我们不能修改的类型:
class Widget { public: Widget(int arg, int i = -1) { } .... };
现在要通过 Create 函数来组一个统一的接口构造对象包括Widget对象和其他对象:
template <class T, class U> T* Create(const U& arg) { return new T(arg); }
如何特化Create() ,使它能够独特处理Widget,简单方案是写出一个 CreateWidget() 来专门处理,那么不能达到我们统一接口 Create() 的目的。
因为无法偏特化一个函数,则无法写出下面代码:
// illegal code, 无法偏特化一个函数 template <class U> Widget* Create<Widget, U>(const U& arg) { return new Widget(arg, -1); }
但我们还有一样工具可用:重载
// 重载机制, 这种机制会轻易构造未被使用的复杂对象,造成额外开销 template <class T, class U> T* Create(const U& arg, T dummy) { return new T(arg); } template <class U> Widget* Create(const U& arg, Widget dummy) { return new Widget(arg, -1); }
幸好,我们有另一种方法减小重载所带来的额外开销:
// 轻量级机制来传递“型别” T 的信息到 Create() 中 // 它没有任何数值,但不同型别却足以区分各个 Type2Type 实体 template <typename T> struct Type2Type { typedef T OriginalType; }; template <class T, class U> T* Create(const U& arg, Type2Type<T>) { return new T(arg); } template <class U> Widget* Create(const U& arg, Type2Type<Widget>) { return new Widget(arg, -1); }
测试:
int main() { // Type2Type string *pStr = Create("hello", Type2Type<string>()); Widget *pW = Create(100, Type2Type<Widget>()); return 0; }