C++模板进阶

1.非类型模板参数

类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。

非类型形参:用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

注意:
1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的
2. 非类型的模板参数必须在编译期就能确认结果

2.类模板的特化

一般情况下,模板可以实现一些与类型无关的代码,但是对于一些特殊的可能会得到一些错误的结果。此时,就需要对模板进行特化。在原模版的基础上,针对特殊类型及逆行特殊化的实现方式。模板特化分为函数模板特化与类模板特化。

2.1函数模板特化

1.必须现有一个基础的函数模板

2.关键字template后面接有一对空的尖括号<>

3.函数名后跟一对尖括号,尖括号中指定需要特化的类型

4.函数形参标:必须要和模板函数的基础参数类型完全相同,如果不同编译器会报奇怪的错误。

// 函数模板 -- 参数匹配
template<class T>
bool Less(T left, T right)
{
 return left < right;
}
// 对Less函数模板进行特化
template<>
bool Less<Date*>(Date* left, Date* right)
{
    return *left < *right;
}
int main()
{
 cout << Less(1, 2) << endl;
 Date d1(2022, 7, 7);
 Date d2(2022, 7, 8);
 cout << Less(d1, d2) << endl;
 Date* p1 = &d1;
 Date* p2 = &d2;
 cout << Less(p1, p2) << endl; // 调用特化之后的版本,而不走模板生成了
 return 0;
}
注意:一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给 出。
bool Less(Date* left, Date* right)
{
 return *left < *right;
}

2.2类模板特化

全特化:将模板参数列表中所有的承诺书都确定化

偏特化:部分特化;参数更进一步的限制。不仅仅是特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。

#include<vector>
#include<algorithm>

template<class T>
struct less
{
    bool operator()(const T& x, const T& y)const//这是less结构体的一个成员函数,//重载了函数条用操作符operator()。它允许less对象像函数一样被调用。//函数参数使用常量引用可以避免复制开销,并确保函数不会修改传入的对象。
    {
        return x < y;
    }
};

int main()
{
    Date d1(2022,7,7);
    Date d2(2022,7,6);
    Date d3(2022,7,8);

    vector<Date> v1;
    v1.push_back(d1);
    v1.push_back(d2);
    v1.push_back(d3);

    sort(v1.begin(),v1.end(),less<Date>());//首先规定范围,最后一个是排序的比较函数对象,//使用less类模板的实例来比较Date对象。就可以实现将Date对象日期按照从早到晚进行排序。

  vector<Date*> v2;
 v2.push_back(&d1);
 v2.push_back(&d2);
 v2.push_back(&d3);
 
 // 可以直接排序,结果错误日期还不是升序,而v2中放的地址是升序
 // 此处需要在排序过程中,让sort比较v2中存放地址指向的日期对象
 // 但是走Less模板,sort在排序时实际比较的是v2中指针的地址,因此无法达到预期
     sort(v2.begin(), v2.end(), Less<Date*>());
    
    //因此,就需要对less类模板按照指针方式特化
    template<>
    struct less<Date*>
    {
        bool operator()(Date* x,Date* y)const
        {
            return *x < *y;
        }
    
};

3.模板总结

优点:模板复用了代码,节省资源,更快的迭代开发,c++的标准模板库(STL)因此而产生

增强了代码的灵活性

缺点:

1. 模板会导致代码膨胀问题,也会导致编译时间变长
2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

4.改错

1、下列的模板声明中,其中几个是正确的( )

1)template

2)template<T1,T2>

3)template<class T1,T2>

4)template<class T1,class T2> 

5)template<typename T1,T2>

6)template<typename T1,typename T2>

7)template<class T1,typename T2>

8)<typename T1,class T2>

9)template<typeaname T1, typename T2, size_t N>

10)template<typeaname T, size_t N=100, class _A=alloc<T>>

11)template<size_t N>

2、

3、

A.模板不支持分离编译,所以不能在.h声明,在.cpp实现

B.由于不支持分离编译,模板程序一般只能放在一个文件里实现

C.不支持分离编译并不是语法错误,而是暂时的编译器不支持,不久将来,或许会被支持

D.模板程序被编译两次,这是不能分离编译的原因所在

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值