C++模板相关知识记录

1.模板的参数列表里除了普通的typename T这样的类型参数之外,还可以定义非类型参数其表示一个值而不是一个类型。并且这个非类型参数是一个常量值,可以用来指定数组大小。

例子:

template <int a,int b> bool CmpStr(const char(&x) [a],const char(&y) [b]){
    return strcmp(x,y)==0;
}

2.编译器遇到一个模板定义时并不会立刻生成代码,只有当我们实例化出模板的一个特定版本时,编译器才会生成代码。

所以在编译模板本身时,编译器只能找找分号丢失或者变量名拼错之类的错误。

比如:

template <typename T> bool IfMax(const T& a,const T& b){
    return not a<=b;
}

如果调用某个自定义类型A:IfMax(A x,A y);

但是A类没有重载小于等于符,那么这个错误只有到实例化的时候才会报错,毕竟之前编译器也根本无从得知你会如何调用模板!

另外,如果模板类的一个成员函数没有被使用,则它不会被实例化。成员函数只有在用到的时候才会被实例化。

3.定义在模板内部的成员函数会被隐式声明为内联函数。

4.可以声明类的友元为类、模板类,模板类的友元为类、模板类。

模板类的友元模板类:

 1 template<typename T> class BlobPtr;
 2 template<typename T> class Blob;
 3 
 4 template<typename T> bool operator==(const Blob<T>&, const Blob<T>&);
 5 
 6 template<typename T> class Blob{
 7     template<typename X> friend class BlobPtr;//一对多,即任何类型的Blobstr类都是友元
 8     //template<typename T> friend class BlobPtr;//一对一,只有T类型的BlobPtr类才是友元
 9     friend bool operator==(const Blob<T>& a, const Blob<T>& b);
10 };

5.不能使用typedef定义一个不确定的模板类,如:typedef Blob<T> sb;  这样是错误的!

但我们可以这样写:template<typename T1,typename T2> using twin=pair<T1,T2>;  

1 template<typename T1,typename T2> using twin=pair<T1,T2>;
2 int main() {
3     twin<int,double> x={1,  2.7};
4     cout<<x.first<<" "<<x.second;
5     getchar();
6     return 0;
7 }

7.如果T是一个模板类的类型参数

T::x有两种含义,一种x为T的静态成员函数/变量,或者x是T类中定义的某种类型,举例如下:

 1 class MyArray 
 2 { 
 3 public:
 4 typedef int LengthType;
 5 static f(){cout<<"9527";}
 6 };
 7 
 8 template<typename T> void MyMethod( T myarr ) 
 9 { 
10 typedef typename T::LengthType LengthType;
11 T::f();
12 }

对于第10行,T::LengthType实际是个类型。

第11行T::f实际是T类的静态成员函数。

对于编译器来说,必须在实例化时确定T::xx到底表示什么。所以如果是变量类型,我们前面要加上typename显式告知编译器后面是一个类型,如果不加编译时会报错。

8.模板函数也可以是inline或者constexpr的,要加在模板参数后面,如:

template<typename t1,typename t2,typename t3>  inline constexpr void f(t1 x1,t2 x2,t3 x3){
    cout<<x1<<x2<<x3;
}

9.一个模板temp<T>每次使用都会实例化,一个文件中的所有对该模板的相同调用(如temp<int>和temp<double>不是同一实例,会实例化两次)共用同一个实例。

但不同文件(CPP)中对该模板的相同调用也会导致多次实例化,避免的方法是先实例化声明再使用该模板

比如你要使用temp<int>,那么你可以在文件开头声明:extern template class temp<int>; 其中的extern表示temp<int>模板的实例化一定在其他一个文件中,那么在这个文件中我们就可以直接使用temp<int>了。

注意模板实际实例化的头文件一定要include进来!

10.普通类/模板类中的成员函数也可以是带模板的,称为成员模板

猜你喜欢

转载自www.cnblogs.com/FdWzy/p/12402043.html