前言:
为了深入了解模板,就必须了解术语实例化和具体化
分类:
隐式实例化、显式实例化、显示具体化
隐式实例化:
指的是当编译器在遇到模板的实际使用时,自动根据传递给模板的参数类型生成相应的特定类型版本的过程。例如,当你调用一个函数模板时,并未明确指定实例化类型,而是通过传入的实参让编译器推断类型:
template <typename T>
void func(T a, T b) { ... }
int main() {
func(1, 2); // 编译器会隐式实例化func<int>(int, int)
}
显式实例化
显式实例化是程序员明确指出模板应该被实例化为哪种特定类型的过程,通常在源文件中独立于模板使用的位置进行
显式实例化可以让编译器提前生成特定类型(如上例中的int
类型)的函数或类模板实例,即使在编译时并没有直接使用到这个实例。这对于库设计者来说尤其有用,他们可以在库实现文件中实例化所有可能用到的模板,以便用户无需看到模板的具体实现也能使用。
// 声明模板
template <typename T>
void func(T a, T b);
// 显式实例化
template void func<int>(int, int);
// 不需要在这里调用func<int>(...);
显式具体化
显式具体化是指完全重新定义一个模板为特定类型的情况,而不是简单地替换模板参数。这是针对模板的一种特殊情况处理,创建的是模板的一个特殊版本,而非所有可能的实例:
// 原始模板
template <typename T>
class MyClass {
...
};
// 显式具体化
template <>
class MyClass<char> {
// 对char类型专门定制的实现
};
在上述例子中,MyClass<char>
是一个显式具体化的类模板,它为字符类型提供了特殊的实现,不同于模板的一般行为。
区别与联系:
- 隐式实例化是自动的,发生在模板使用的地方,编译器根据上下文推断并生成实例。
- 显式实例化是手动的,允许程序员控制何时何地实例化模板,而且可以实例化那些并未在当前编译单元中直接使用的模板版本。
- 显式具体化是一种特殊情况,它不是生成模板参数替换后的通用实例,而是专门为某一特定类型提供完全不同的实现。
简而言之,隐式实例化是编译器基于使用情况自动推导并生成实例;显式实例化是开发者强制编译器生成特定类型实例;而显式具体化则是为特定类型编写非一般模板规则的专用实现。