模板之型别对型别的映射
假设 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;
}
还没有评论,来说两句吧...