从C到C++【模版进阶】

64 阅读1分钟

一、非类型的模版

类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称 非类型行参:用常量作为作为模版的一个参数

//通常只能是整形,传浮点型错误
template<class T,size_t n=10>
class ARRAY
{
public:
    ARRAY()
    :_arr(new T[n])
    ,_size(0)
    {

    }
private:
    T* _arr;
    size_t _size;
};
int main()
{
    ARRAY<int,100> arr1;
    ARRAY<int> arr2;
    int a=10;
    //错误,必须常量
    ARRAY<int,a> arr3;
    return 0;
}

这样做的好处在于我们可以随时定义不同大小的ARRARY,在C语言中我们不可能定义多种不同大小的ARRAY

二、模版的特化

模版的特化分类函数模版特化和类模版特化2种

2.1 函数模版特化

class Date
{
public:
    Date(int year=2023,int month=3,int day=8)
    :_year(year)
    ,_month(month)
    ,_day(day)
    {
    }
    bool operator<(const Date& d)
    {
        if(_year<d._year)
        {
            return true;
        }
        else if(_year==d._year&&_month<d._month)
        {
            return true;
        }
        else if(_year==d._year&&_month==d._month&&_day<d._day)
        {
            return true;
        }
        return false;
    }
private:
    int _year;
    int _month;
    int _day;
};
template<class T>
bool Less(T& left,T& right)
{
    return left<right;
};
int main()
{
    Date d1;
    Date d2(2024,1,1);
    //输出true
    cout << Less(d1,d2) << endl;

    Date* d3=&d1;
    Date* d4=&d2;
    //输出false 这里不是我们想要的结果
    //原因在于我们没有针对Date*进行特别处理
    cout << Less(d3,d4) << endl;
}

上面的程序在遇到指针类型的时候输出和我们预计的不相符,所以这时需要我们针对他进行特别处理

bool Less(Date* left, Date* right) {
    return *left < *right;
}

�同时也可以写成这样,不过这段代码在clion跑不了,具体原因我也不是很清楚

template<>
bool Less<Date*>(Date* left, Date* right) {
    return *left < *right;
}

2.2 类模版特化

template<class T1, class T2>
class Data
{
public:
    Data() {cout<<"Data<T1, T2>" <<endl;}
private:
    T1 _d1;
    T2 _d2;
};
template<>
class Data<int, char> {
public:
    Data() {cout<<"Data<int, char>" <<endl;}
private:
    int _d1;
    char _d2;
};

int main()
{
    //执行第一个
    Data<int, int> d1;
    //执行第二个
    Data<int, char> d2;
}

�还有一种特化方式叫做偏特化

template<class T1, class T2>
class Data
{
public:
    Data() {cout<<"Data<T1, T2>" <<endl;}
private:
    T1 _d1;
    T2 _d2;
};
template<>
class Data<int, char> {
public:
    Data() {cout<<"Data<int, char>" <<endl;}
private:
    int _d1;
    char _d2;
};
// 将第二个参数特化为int
template <class T1>
class Data<T1, int> {
public:
    Data() {cout<<"Data<T1, int>" <<endl;}
private:
    T1 _d1;
    int _d2;
};
int main()
{
    //执行第一个
    Data<int, int> d1;
    //执行第二个
    Data<int, char> d2;
    //执行第三个
    Data<char,int> d3;
}

总结:有全特化用全特化,有偏特化用偏特化,最后才用普通的模版