目录
模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。
函数模板
函数模板可以简化函数重载的代码。格式:template<class T1, class T2,...>接函数的定义。class也可以用typename替换。
调用时,在函数名后面跟上<类型>可以显示实例化函数模板,即使参数类型和显示实例化的不一样,编译器会进行隐式类型转换。
如果没有显示实例化,编译器会根据实参类型推导模板类型。
如果没有显示实例化,也没有与传递的参数匹配的函数模板,编译器将会报错。
函数重载和函数模板可以同时存在,编译器会自动匹配最合适的参数类型来进行函数调用。
template<class T>
T add(const T& x,const T& y)
{
return x + y;
}
int main()
{
int a = 1;
int b = 1;
int sum1 = 0;
sum1 = add(a, b);
cout << sum1 << endl;
int c = 3;
double d = 1.2;
int sum2 = 0;
//显示实例化
//涉及到隐式类型转换
sum2 = add<int>(c, d);
//类型不同,没有与之匹配的函数模板会报错
//sum2 = add(c, d);
cout << sum2 << endl;
return 0;
}
类模板
类模板可以根据元素的不同类型来调整容器。只需要根据需求来传递模板参数即可。
非类型模板参数
顾名思义,非类型模板参数就是模板的参数不是类型,它只能是一个整型值。template<class T, size_t N = 10>在编译时,会将N替换成10。
模板特化
函数模板特化
一个单纯的比较函数模板有时无法满足自身的需求。那么就需要函数模板的特化,即特殊化。
模板特化需要注意以下几点:
1.必须要先有一个基础的函数模板
2.关键字template后面接一对空的尖括号<>
3.函数名后跟一对尖括号,尖括号中指定需要特化的类型
4.函数形参表: 必须要和模板函数的基础参数类型完全相同
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
bool operator<(const Date& d)const
{
return (_year < d._year) ||
(_year == d._year && _month < d._month) ||
(_year == d._year && _month == d._month && _day < d._day);
}
bool operator>(const Date& d)const
{
return (_year > d._year) ||
(_year == d._year && _month > d._month) ||
(_year == d._year && _month == d._month && _day > d._day);
}
friend ostream& operator<<(ostream& _cout, const Date& d);
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
//函数模板特化
template<class T>
bool Less(const T& x, const T& y)
{
return x < y;
}
//特化一个模板来比较指针
template<>
//error
//bool Less<Date*>(const Date*& x, const Date*& y)
//要未特化的模板参数匹配
bool Less<Date*>( Date* const & x, Date* const & y)
{
return *x < *y;
}
int main()
{
int a = 10;
int b = 20;
cout << Less(a, b) << endl;
Date d1({ 2025,5,29 });
Date d2({ 2025,5,30 });
cout << Less(d1, d2) << endl;
//比较的是指针
cout << Less(&d1, &d2) << endl;
//比较结果会变
//每次创建的空间的指针不一样
//走模板特化就不会,因为其比较的是内容
Date* d3 = new Date(2025, 5, 20);
Date* d4 = new Date(2025, 5, 21);
cout << Less(d3, d4) << endl;
}
类模板的特化
类模板的特化分为全特化和偏特化。同样在模板特化前需要主模板的声明。
//类模板特化
template<class T1 ,class T2>
class Date
{
public:
Date()
{
cout << "Date()" << endl;
}
private:
T1 _d1;
T2 _d2;
};
//模板特化之前也要写明原模板
//全特化
template<>
class Date<int, char>
{
public:
Date()
{
cout << "Date<int char>" << endl;
}
private:
int _d1;
char _d2;
};
//偏特化
template<class T1>
class Date<T1, char>
{
public:
Date()
{
cout << "Date<T1, char>" << endl;
}
private:
T1 _d1;
char _d2;
};
//偏特化
//传指针版本
template<class T1, class T2>
class Date<T1*, T2*>
{
public:
Date()
{
cout << "Date<T1* ,T2*>" << endl;
}
private:
T1 _d1;
T2 _d2;
};
//偏特化
//传引用版本
template<class T1, class T2>
class Date<T1&, T2&>
{
public:
Date()
{
cout << "Date<T1& ,T2&>" << endl;
}
private:
T1 _d1;
T2 _d2;
};
一定要将模板的声明和定义放在一个.h文件中。 否则会出现链接问题。
"💻✨ 下期再见,Happy Coding!"