C++学习笔记(七) 模板与泛型编程(二)

2014-11-24 11:31:53 · 作者: · 浏览: 1
ass A{
//other definition
T d1;
V d2;
};

template
class A{
//other definition
T d1;
int d2;
};

在偏特化中,我们将模板参数V特化为int,需要注意的是,偏特化后的模板仍然是一个模板类,而非实际的类。
模板元编程
所谓模板元编程实际上并没有引入新的C++特性,它是C++非类型模板与模板特化的一个非常奇妙的用法。它能够将一

些运行时计算的任务放到编译期来完成,从而提高运行效率。例如,我们希望以常量的阶乘作为一个静态数组的大小

,就可以利用模板元编程了:
[cpp]
template
class Factorial {
public:
unsigned VALUE = N*factorial::VALUE;
};

template<>
class Factorial<0> {
public:
unsigned VALUE = 1;
};

上面的模板类Factorial用于计算阶乘,它巧妙的利用递归在编译器就可以计算出我们所需要的阶乘值,值得注意的

是,这里的递归出口是一个偏特化模板,很神奇吧。
模板的编译机制
谈完模板的一些基本特性与使用方式,我们最后来看一下模板编译机制。我们知道,模板只是提供被编译器供编译器

生成实例的一种方式。而模板是按需进行实例化的,也就是说,如果我们按照我们的习惯将类模板的定义放在头文件

里,而将其成员函数的实现放在源文件中,在对定义源文件进行编译时是不会生成任何代码的,这样在其他使用文件

中因为只包含器类的定义而不包含实现,在连接过程中就会发生找不到类的错误。所以我们的模板代码必须全部放在

头文件中,如果你为了方便管理,也可以讲实现放在源文件中,再通过头文件进行反包含。有些童鞋可能会担心重定

义的问题,实际上把模板放在头文件中,这种C++标准中是运行的,编译器对它做了特殊处理,所以不会有普特类的

定义放在头文件中的担心。
实际上在C++的标准中还有一个关键字export可以解决这个问题,不过由于目前还没多少编译器支持,所以这里也就

不谈了。
模板的编译机制是按需的,不仅对于类型按需,对于那些并没有使用到的成员函数,编译器也不会对它进行编译的,

这点很重要。前段时间,在网上翻博客时就碰见一位仁兄讲述的一个例子,他自己做了一个简单的模板库,在测试的

时候没有问题,但在实际的使用过程中却碰到了大麻烦。因为他在测试时,对于有些类型并没有用到所有的成员函数

,而这些成员函数编译器就没有对它进行编译,这才使问题在使用期才暴露出来。所以,了解模板的编译机制,对于

我们以后开发自己的模板库有很重要的作用。

作者:justaipanda