相信大家对模板并不陌生,模板的基本概念我想就不用多说了。大多数人包括我自己对模板的理解就是“T容器”。
请看下面的代码:
template<int
Physical<m1+m2,
{
}
头一次见到template的这种用法时,我确实有点目眩。看来我们对模板的认识只是皮毛而已
在当今的程序设计中模板已经显露出它的价值来了,比如STL全部都是以模板架构的。自VS2003(VC7)以来的编译器也对模板提供了更多的支持。
我们需要对模板有更进一步的认识,下面就让我们进入模板的世界。
- 模板的特性
首先来看一个例子:
template<int
int
int
你能看出这两个函数的区别在哪里吗?
它们的区别就在于,Func1的参数是编译期指定,如Func1<0>()
这正体现了模板的特性或者说是它的技术核心,就是编译期的动态机制,这种机制使程序在运行期具有更大的效率优势。
到此你是不是对本文开头那段代码有了更深入的理解了呢?
模板的另一个特性是,如果一个模板没有被特化,那么编译器根本不会去理会它,也就是说模板内的代码被隐藏了。
- 函数模板与类模板
这是一个函数模板:template<class
函数模板的模板参数是隐式的,编译器会自动根据传入值的类型来确定模板参数的类型。因此函数模板的模板参数不能有默认值。
这是一个类模板:template<class
类模板的模板参数是显式的,使用一个模板类时必须指明其模板参数,因此类模板的模板参数可以有默认值。
我们还可以做更多的事情,比如MyClass可以派生自T(XTP界面库就是这么做的),在MyClass内部可以使用关于T的enum、typedef等等。这些将在下文一一谈到。
(我在这里提出一个建议,创建一个类模板,请记得第一件事就是对模板参数进行typedef定义。)
- 模板的部分特化与应用
模板最有价值的地方就是它的部分特化,也是应用最广泛的特性。
所谓“部分特化”也就是说,一个模板有多个参数,但我们只对其中一部分参数进行特化,或者是只针对常量模板参数的某种情况进行特化。
编译期ASSERT
这是对bool型模板参数部分特化的一个例子。最简单的实现:
template<bool>
template<>
当我们将一个表达式作为模板参数,而这个表达式的值为false时,编译器就找不到合适的实现,便会报错了。
我们可以将它扩展一下:
template<bool>
template<>
#define
{/
}
当然,事实是编译期可用的表达式或函数(如sizeof、__alignof)数量上并不太多,但是这种方式是有着积极意义的。
常量映射为类型
请看这样一个模板:template<int
模板参数的不同数值,就会产生不同类型的Int2Type。即Int2Type<0>不同于Int2Type<1>,以此类推。
我们可以利用这个模板实现编译期分派。看这样一个例子:
template<class
class
{
{
{
……
}
else
{
……
}
}
};
显然,编译器不会让你侥幸成功。而使用了