【C++】模板

一、什么是模板

模板是一种编程工具。它可以让代码具有通用性(让多个不同的类型使用同一个模板)。

模板的声明:

template<class T>

template<typename T>

 二、模板

2.1函数模板

将函数的参数用模板表示。

template<class T>
void Swap(T& a, T& b)//T为模板类型(可以是任何类型)
{
    T c = a;
    a = b;
    b = c;
}

int main() {
    int a = 0;
    int b = 1;
    char c = 0;
    swap(a, c);//T无法代表两种不同的类型,这么写会报错
    Swap(a, b);//编译器会自动推导出参数的类型
    cout << "a:" << a << endl;
    cout << "b:" << b << endl;
}

当然,函数模板也能作为返回类型。

template<class T>
//T也可以作为返回类型
T Add(T& a, T& b)
{
    return a + b;
}

int main() {
    int a = 0;
    int b = 1;
    //不想用自动类型推导,可以用<>来指定类型传参
    cout << Add<int>(a, b) << endl;
}

模板类型也可以定义多个,每个模板类型互不相通,但也可以转为同一个类型。

template<class T,class Y>
T Add(T& a, Y& b)
{
    cout << "函数模板调用";
    return a+b;
}

int main() {
    int a = 0;
    char b = 1;
    cout << Add(a, b) << endl;//此时的T是int Y是char
    cout << Add(a, c) << endl;//此时的T是int Y也是int
}

注:*模板作为返回类型时,该参数中至少有一个参数的类型也是同名模板,否则编译器无法得知你要返回什么。

template<class T>
    //参数中没有T类型,编译器无法得知你想返回什么
T Add(int& a, int& b)
{
    return a + b;//万一你想返回char呢?
}

int main() {
    int a = 0;
    int b = 1;
    cout << Add(a, b) << endl;
}

       *模板调用的优先级:能调用普通函数时,不会调用模板函数。

 使用 “ <> ”  可以指定编译器调用模板。

 2.2模板特化

模板不是万能的,模板也解决不了某些情况。如:

class Date
{
public:
    Date(int day)
    {
        _day = day;
    }
public:
    int _day = 0;
};

template<class T>
int Add(T& a, T& b)
{
    cout << "函数模板调用";
    return a+b;
}

int main() {
    Date d1=1;
    Date d2=2;
    cout << Add(d1, d2) << endl;//自定义类型无法比较,运行会报错
}

此时使用模板特化,让模板函数遇到这种情况时特殊处理。

class Date
{
public:
    Date(int day)
    {
        _day = day;
    }
public:
    int _day = 0;
};

template<class T,class Y>
int Add(T& a, Y& b)
{
    cout << "函数模板调用";
    
    return a+b;
}

template<>
int Add<Date,Date>(Date& d1,Date& d2)//使用该句式特化模板
{
    cout << "模板特化";
    return d1._day + d2._day;
}
int main() {
    Date d1=1;
    Date d2=2;
    cout << Add(d1, d2) << endl;//传入模板特化指定的类型后,就会调用特化模板
}

2.3类模板

2.3.1类模板的创建

模板也适用于类。

模板类中的成员函数在调用时才会被创建。普通成员函数在一开始就会创建。

template<class T = int>//类模板的模板参数可以有默认值
class Date
{
public:
    Date(T day):_day(day)
    {
        _day = day;
    }
    T showday()
    {
        cout << _day << endl;
    }
public:
    T _day = 0;
};

int main() {
    Date<int> d1=1;//类模板没有自动类型推导
    Date<char> d2=2;//需要手动添加类型

    Date<>d3 = 3;//使用默认值
}

 2.3.2模板类对象做函数参数

template<class T = int>
class Date
{
public:
    Date(T day):_day(day)
    {
        _day = day;
    }
    void showday()
    {
        cout << _day << endl;
    }
public:
    T _day = 0;
};
//三种传参方式
void show(Date<char>& d)//指定类型传参
{
    d.showday();
}

template<class T>
void show(Date<T>& d)//参数模板化传参
{
    d.showday();
}

template<class T,class Y>
int Add(T& a, Y& b)//对象模板化传参
{
    cout << "函数模板调用";
    return a+b;
}
template<>
int Add<Date<int>, Date<int>>(Date<>& d1, Date<int>& d2)
{
    cout << "模板特化";
    return d1._day + d2._day;
}

2.3.3模板类成员类外实现

类外实现的模板类成员需要重新写一遍template

template<class T = int>
class Date
{
public:
    Date(T day);
    void showday();
    
public:
    T _day = 0;
};
//成员函数类外实现
template<class T>
Date<T>::Date(T day)
{
    _day = day;
}

template<class T>
void Date<T>::showday()
{
    cout << _day;
}

注:模板类不能分文件编写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值