1.函数模板(泛型)
- 语法:template<typename T>或template<class T>(T只是个符号,可以换成其它的字符)
template<class T,class N,…>
void swapInt(int a,int b){
int temp;
temp = a;
a = b;
b = temp;
}
void swapDouble(double a,double b){
double temp;
temp = a;
a = b;
b = temp;
}
template<typename T>
void Swap(T &a,T&b){
T temp = a;
a = b;
b = temp;
}
int main(){
int a = 123;
int b = 21;
Swap(a,b);
cout << a << "," << b << endl;
Swap<int>(a,b);
cout << a << "," << b << endl;
return 0;
}
- 普通函数与函数模板的区别
- 普通函数调用可以发生隐式类型转换
- 函数模板用自动类型推导,不可以发生隐式类型转换
- 函数模板用显示类型,可以发生隐式类型转换
#include <iostream>
using namespace std;
#include <string>
int f(int a,int b){
return a + b;
}
template<class T>
T ff(T a,T b){
return a + b;
}
int main(){
int a = 12;
int b = 23;
cout << f(a,b) << endl;
char c = 'c';
cout << f(a,c) << endl;
cout << ff(a,b) << endl;
cout << ff<int>(a,c) << endl;
}
- 普通函数和函数模板的调用规则
- 二者皆可调用时,优先调用普通函数
- 可以通过空模板参数列表来强制调用函数模板
- 函数模板也可以发生重载
- 如果函数模板可以产生更好的匹配,优先调用函数模板
#include <iostream>
using namespace std;
#include <string>
int f(int a,int b){
cout << "调用普通函数" << endl;
return a + b;
}
template<class T>
T f(T a,T b){
cout << "调用函数模板" << endl;
return a * b;
}
template<class T>
T f(T a){
cout << "调用函数模板" << endl;
return a;
}
int main(){
int a = 12;
int b = 23;
cout << f(a,b) << endl;
cout << f<>(a,b) << endl;
cout << f(a) <<endl;
char x = 'x';
char y = 'y';
cout << f(x,y) << endl;
}
- 模板的局限性
并非所有的泛型都满足函数体内部的操作
#include <iostream>
using namespace std;
#include <string>
template <class T>
T f(T a,T b){
return a + b;
}
class Person{
public:
Person(int x){
this -> x = x;
}
int x;
};
int main(){
int a = 123;
int b = 234;
cout << f(a,b) << endl;
Person p1(12);
Person p2(23);
}
#include <iostream>
using namespace std;
#include <string>
template <class T>
T f(T a,T b){
return a + b;
}
class Person{
public:
Person(int x){
this -> x = x;
}
int x;
};
template<>Person f(Person a,Person b){
Person c(0);
c.x = a.x + b.x;
return c;
}
int main(){
int a = 123;
int b = 234;
cout << f(a,b) << endl;
Person p1(12);
Person p2(23);
cout << f(p1,p2).x <<endl;
}
2.类模板
- 语法:与函数模板一致,在类前加template <class T>
#include <iostream>
using namespace std;
#include <string>
template <typename T,typename N>
class Person{
public:
Person(T age,N name){
this -> age = age;
this -> name = name;
}
T age;
N name;
};
int main(){
Person<int,string> p1(123,"A");
cout << p1.age <<p1.name <<endl;
}
- 类模板与函数模板的区别
- 类作为函数参数
#include <iostream>
using namespace std;
#include <string>
template <typename T,typename N>
class Person{
public:
Person(T age,N name){
this -> age = age;
this -> name = name;
}
T age;
N name;
};
void f(Person<int,string> p1){
cout << p1.age << "," << p1.name <<endl;
}
int main(){
Person<int,string> p1(123,"A");
f(p1);
return 0;
}
void f(Person<int,string> p1){
cout << p1.age << "," << p1.name <<endl;
}
template<class T>
void f(T p1){
cout << p1.age << "," << p1.name <<endl;
}
- 类模板与继承
- 当父类是一个类模板时,子类在声明时需指定父类参数的类型
- 不指定,编译器无法给子类分配内存
- 要想灵活指定父类T的类型,子类也需转为类模板
#include <iostream>
using namespace std;
#include <string>
template <class T,class N>
class Person{
public:
Person(){cout << "aaaaa" << endl;};
Person(T age,N name){
this -> age = age;
this -> name = name;
cout << "aacccca" << endl;
}
T age = 1;
N name = "a";
};
class Person1:public Person<int,string>{
public:
Person1(){};
Person1(int a,string b):Person(a,b){
}
void f(){
cout << this -> age << "," << this -> name << endl;
}
};
int main(){
Person1 p1(12,"a");
p1.f();
return 0;
}
template <class T,class N>
class Person1:public Person<T,N>{
public:
Person1(){};
Person1(T a,N b):Person<T,N>(a,b){
}
void f(){
cout << this -> age << "," << this -> name << endl;
}
};
int main(){
Person1<int,string> p1(12,"a");
p1.f();
return 0;
}
#include <iostream>
using namespace std;
#include <string>
template <class T,class N>
class Person{
public:
Person(){cout << "aaaaa" << endl;};
Person(T age,N name);
void f();
T age = 1;
N name = "a";
};
template <class T,class N>
Person<T,N>::Person(T age,N name){
this -> age = age;
this -> name = name;
cout << "aacccca" << endl;
}
template <class T,class N>
void Person<T,N>::f()
{
cout << this -> age << "," << this -> name << endl;
}
int main(){
Person<int,string> p(12,"a");
p.f();
return 0;
}
- 类模板与友元
#include <iostream>
using namespace std;
#include <string>
template <class T,class N>
class Person{
friend void f(Person<T,N> p){
cout << p.age << "," << p.name << endl;
public:
Person(T age,N name){
this -> age = age;
this -> name = name;
}
T age;
N name;
}
};
int main(){
Person<int ,string> p(12,"a");
f(p);
}
#include <iostream>
using namespace std;
#include <string>
template <class T,class N>
class Person;
template <class T,class N>
void f(Person<T,N> p){
cout << p.age << "," << p.name << endl;
}
template <class T,class N>
class Person{
friend void f<>(Person<T,N> p);
public:
Person(T age,N name){
this -> age = age;
this -> name = name;
}
T age;
N name;
};
int main(){
Person<int ,string> p(12,"a");
f(p);
}