现在的位置: 首页 > 综合 > 正文

模板之型别对型别的映射

2018年03月30日 ⁄ 综合 ⁄ 共 995字 ⁄ 字号 评论关闭

假设 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;
}

抱歉!评论已关闭.