c++ template模板

1 篇文章 0 订阅
1 篇文章 0 订阅

函数模板会进行严格的类型匹配,模板类型不提供隐式类型转化
普通函数能够进行自动类型转换
 
函数模板重载四大规则
1 函数模板可以像普通函数一样被重载
2 C++编译器优先考虑普通函数
3 如果函数模板可以产生一个更好的匹配,那么选择模板
4 可以通过空模板实参列表的<>语法限定编译器只通过模板匹配
5 模板的实例化类型确定是在编译期间
6 函数查找顺序:1,找普通函数或类;2,如果1找不到,则找模板.3,如果2找到模板,就找匹配度高(特化)模板或特殊模板.4,如果3找不到,则使用普通模板.
7 特例化本质上我们顶替了编译器的工作,帮编译器做了类型推导.类的偏特化本质上还是一个模板,是源模板的一个子集.而全特化则是一个实例(但仍是模板).
8 因为是编译器的工作,因此,一系列特化版本必须与源模板在一个文件中
9 特化的类型可以是const T*, T&, const T&, T*等
10 模板参数:和函数参数类似.如template<class T,int count> 如template<class T,int count = 100>
11 函数模板不是函数,而是模板.
 
模板特化按对象类型(类和函数)分为两种:类模板特化和模板函数的特化。
类模板有偏特化      因为类不能重载
函数模板没有偏特化   因为函数能重载
特化与偏特化可以理解为模板的实例化程度。
 //类模板
 template<class T1, class T2>
 class D
 {
     public:
     void test()
     {
        cout << "类模板无特化 又称为基础类模板 " << endl;
     }
 };
 
 //类模板的偏特化 指明了一部分类型  class D <T1 &, int> class D <T1 *, int> class D <T1 *, T2 *>
 template<class T1>
 class D <T1, int>
 {
     public:
     void test()
     {
         cout << "类模板的偏特化" << endl;
     }
 };
 
 //类模板的全特化 指明了全部类型 
 template<>
 class D <int,int>
 {
     public:
     void test()
     {
         cout << "类模板的全特化" << endl;
     }
 };
 
 void main1()
 {
     D<char *, char *> d1;//无特化
     d1.test();
     D<char *, int> d2;//偏特化
     d2.test();
     D<int, int> d3;//全特化
     d3.test();
162 }
 


void test(int a, char *p)
{cout << "普通函数" << endl;}

template<class T1,class T2> 
void test(T1 t1, T2 t2) 
{cout << "普通函数模板" << endl;}

template<>
void test<int, char *>(int t1, char *t2)
{cout << "函数模板全特化" << endl;}

void main2()
{
    int a;
    char *p;
    test(a,p);//普通函数
    test<>(a,p);//函数模板全特化 <>使其使用函数模板
    test<int,char*>(a,p);//函数模板全特化
    test<>(a,a);//普通函数模板
    //尝试定义偏特化,结果出错.C++不允许其存在.
}
 
 
 
训练:
  1. template<typename T> void f(T);/* a */  
  2. template<typename T> void f(T*);/* b */  
  3. template< > void f<int>(int*);/* c */  
  4. int* p;  
  5. f(p);     //1、调用上面拿个版本??? 
  6. 1, 
  7.   
  8. template<typename T> void f(T);/* a */  
  9. template< > void f<int*>(int*);/* b */  
  10. template<typename T> void f(T*);/* c */  
  11. int* p;  
  12. f(p);     //2、这里又调用哪个版本? 
答案:c,c
解析:
1,a,b是基础模板,b的匹配度更高,因此选择了b;c是b的特化,并且匹配,因此最终选择了c
2,a,c是基础模板,c的匹配度更高,而c无特化版本,因此最终选择了c.

//基础模板
//template<class T>
//void test1(T t)
//{cout << "a" << endl;}


//基础模板
template<class T>
void test1(T *t) 
{cout << "b" << endl;}


//基础模板
template<class T>
void test1(T &t) 
{cout << "c" << endl;}


//明显是a的全特化
//template<>
//void test1<int *>(int *p)
//{cout << "1" << endl;}


//明显是b的全特化
template<>
void test1<int>(int *p) 
{cout << "2" << endl;}


//明显是c的全特化
template<>
void test1<int >(int &)
{cout << "3" << endl;}.

void main3()
{
    int n = 1;
    test1(n);//多义:a和c  注释掉其中一个后:3
    int *p = &n;


    //先匹配基础模板,发现b最合适.便以b为基础进行特化模板挑选
    test1(p);//2
    test1(&p);//b
    test1(&n);//2
}



此外,还有特殊的模板,后期我会慢慢总结.
 

c++11新特性:可变模板参数:可变模板参数函数和可变模板参数类.















 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值