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.定义在模板内部的成员函数会被隐式声明为内联函数(普通类也是!!!!!之前不知道)。

如果在类体中定义的成员函数中不包括循环等控制结构,C++系统会自动将它们作为内置(inline)函数来处理。

 

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.普通类/模板类中的成员函数也可以是带模板的,称为成员模板

 

11.尾置返回允许在参数后声明返回类型:

template <typename T> auto f(T iter) ->decltype(*iter){//利用尾置返回,返回形参的解引用类型。
    return *iter;
}

int main()
{
    vector<int> p={1,2,3};
    cout<<f(p.begin());
    getchar();
}

上面的f函数由于返回*T类型,但在声明参数前没法引用iter,即下面的写法是错误的:

C++模板相关知识记录

 

 只能用上面的尾置返回。

原文链接: https://www.cnblogs.com/FdWzy/p/12402043.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++模板相关知识记录

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/333856

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午9:23
下一篇 2023年3月1日 下午9:23

相关推荐