1.C++模板的基本语法
template<typename T>//typename可替换为class
void myswap(T& a, T& b)//写完template后紧跟所需要写的函数,且函数必须包含T类型
举个简单例子,交换两个字符
template<typename T>
void myswap(T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}
int main()
{
int a=10;
int b=20;
char c='f';
char d='h';
myswap(a, b);
myswap(c, d);
cout << a << " " << b << endl;
cout << c << " " << d << endl;
return 0;
}
运行结果
由此分析可得模板的优点
无论使用交换int类型的数还是char类型,最终都能够转换,相比普通函数来说能够更加方便
对于普通函数则需要写出整形交换和char类型交换才能实现。
2.普通函数与模板函数的区别
(1)普通函数比模板函数更快
(2)普通函数优先调用
······如:
void myPrint(int a, int b)
{
cout << "普通函数调用!" << endl;
}
template<class T>
void myPrint(T a, T b)
{
cout << "模板函数调用!!" << endl;
}
void test()
{
int a = 10;
int b = 20;
myPrint(a, b);
}
int main()
{
test();
return 0;
}
结果可得在同时有普通函数和模板函数时不会报错而是普通函数调用
但是如果在调用的时候使用强制模板调用
myPrint<>(a, b);
则会调用模板函数
(3)模板函数也可进行重载
template<class T>
void myPrint(T a, T b)
{
cout << "模板函数调用!!" << endl;
}
template<class T>
void myPrint(T a, T b,T c)//进行模板函数重载
{
cout << "重载模板函数调用!!" << endl;
}
void test()
{
int a = 10;
int b = 20;
int c = 30;
myPrint<>(a, b,c);//调用模板函数
}
(4)如果函数模板拥有更好的匹配,则优先使用函数模板(什么意思呢)
void myPrint(int a, int b)
{
cout << "普通函数调用!" << endl;
}
template<class T>
void myPrint(T a, T b)
{
cout << "模板函数调用!!" << endl;
}
void test()
{
char c1 = 'a';
char c2 = 'b';
myPrint(c1, c2);
}
int main()
{
test();
return 0;
}
运行结果
因为是char类型,如果调用普通函数,则需要将a和b转换成int类型,而模板函数则不需要转换类型可直接使用char类型进行调用,因此会优先使用模板函数调用。
3.模板的局限性
(1)特定的数据类型需要使用具体化方式做特殊实现
如:对比两个数据是否相等的函数
#include<iostream>
#include<string>
using namespace std;
template<class T>
bool mycompere(T a, T b)
{
if (a == b)
return true;
else
return false;
}
void test()
{
int a = 10; int b = 20;
bool ret = mycompere(a, b);
if (ret)
{
cout << "a==b" << endl;
}
if (!ret)
{
cout << "a!=b" << endl;
}
}
int main()
{
test();
return 0;
}
这个代码能够正常运行出a!=b;
但如果把a和b换成对象。
如以下
#include<iostream>
#include<string>
using namespace std;
template<class T>
bool mycompere(T a, T b)
{
if (a == b)
return true;
else
return false;
}
class Person
{
public:
string m_name;
Person(string name)
{
this->m_name = name;
}
};
void test()
{
//int a = 10; int b = 20;
Person p1("张三");
Person p2("李四");
bool ret = mycompere(p1, p2);
if (ret)
{
cout << "a==b" << endl;
}
if (!ret)
{
cout << "a!=b" << endl;
}
}
int main()
{
test();
return 0;
}
则不能运行
因此需要具体化操作
由于在这里比较的是Person类的对象,因此需要将T换成Person
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
string m_name;
Person(string name)
{
this->m_name = name;
}
};
template<class T>
bool mycompere(T &a, T &b)
{
if (a == b)
return true;
else
return false;
}
template<>
bool mycompere(Person &a, Person &b)//利用具体化的Person来实现具体化优先调用
{
if (a.m_name == b.m_name)
return true;
else
return false;
}
void test()
{
//int a = 10; int b = 20;
Person p1("张三");
Person p2("李四");
bool ret = mycompere(p1, p2);
if (ret)
{
cout << "a==b" << endl;
}
if (!ret)
{
cout << "a!=b" << endl;
}
}
int main()
{
test();
return 0;
}
(2)如果是数组就无法实现
3.类模板
(1)类模板的基本语法
template<class T>//即在下一行写类而不是函数即为类模板
类//模板类
举例子:
#include<iostream>
#include<string>
using namespace std;
template<class nametype,class agetype>
class Person
{
public:
Person(nametype name, agetype age)
{
m_name = name;
m_age = age;
}
void showPerson()
{
cout << "name: " << m_name << endl;
cout << "age: " << m_age << endl;
}
nametype m_name;
agetype m_age;
};
void test01()
{
Person<string, int>p("Tom", 10);
p.showPerson();
}
int main()
{
test01();
return 0;
}
(2)类模板和函数模板的区别
a.类模板在模板参数列表中可以有默认参数
如上图(1)代码
#include<iostream>
#include<string>
using namespace std;
template<class nametype,class agetype =int>//可把agetype换成int类型来实现默认参数
class Person
{
public:
Person(nametype name, agetype age)
{
m_name = name;
m_age = age;
}
void showPerson()
{
cout << "name: " << m_name << endl;
cout << "age: " << m_age << endl;
}
nametype m_name;
agetype m_age;
};
void test01()
{
Person<string>p("Tom", 10);//这里就可以默认参数,把int删掉
p.showPerson();
}
int main()
{
test01();
return 0;
}
b.类模板没有自动类型推导的使用方式
(如上图(1)代码)
Person<string, int>p("Tom", 10);
Person p2("Tom", 1000);//错误会报错,无法自动类型推导
(3)类模板中成员函数的创建时机
a.普通类中的成员函数一开始就能创建
b.类模板中的成员函数在调用的时候才能创建