c++模板
1.模板
模板的声明有两种:template <typename Type>或者template<class Type>,虽然建议使用typename以避免二义性,但是这两种实际上是都可以的。
函数模板:
template <class type> ret-type func-name(parameter list)
{
// 函数的主体
}
类模板:
template <class type> class class-name {
//类主体
}
3.问题
问题1:当编译器遇到一个模板定义时,它并不生成代码。只有我们实例化出模板的一个特定版本时,编译器才会生成代码,因此模板的实例化发生在编译时。
问题2:下面这两种方式编译时会出现错误,即模板类的声明和定义必须放到同一个文件中,模板类成员函数的声明和定义必须放到同一个文件中,这是为什么?
其实这是一个问题。
首先类模板成员函数声明和定义分离时可以编译成功(即可以编译出main.o),这是因为可以在temp.h里面找到模板的声明。但是链接时会出错,链接的时候会实例化模板,但是此时却找不到模板类的定义,因为temp.cpp生成的temp.o文件里面并没有模板类的符号(因为temp.cpp里面并没有实例化模板)。
所以通常是把模板的声明和定义放到同一个头文件里面,这样在编译main.cpp的时候会直接实例化一个类模板,所以链接的时候就不会出错。另外一个方法是在temp.cpp里面显式的实例化一个模板类,即在temp.cpp文件中加一行:
template class A<int>;
这个时候编译生成的temp.o文件中便有了类的符号,因此可以链接成功(但是这样兼容性不好,其他地方使用模板的类型都要在temp.cpp中显式实例化)。
问题3:与普通函数和类不同,模板函数或类在其他类作为友元之前必须先进行声明(不用定义,声明即可),否则无法通过编译,例如:
template<typename T>class A; //类模板声明,不加这一行会编译错误
template<typename T> class B {
friend class A<T>;
}