为什么要有函数模板?写了两个函数用来实现int型求和与double型求和,这两个函数只是返回值和参数类型不同,基本功能是一样的,但是却需要写两个函数,当这样功能一样的函数变多之后就要用到函数模板来减少工作量。
#include <iostream>
using namespace std;
/*int add(int x, int y)
{
return (x + y);
}
double add(double x, double y)
{
return x + y;
}*/
template <typename T>
T add(T x, T y)
{
return x + y;
}
template <typename T1, typename T2>
void print(T1 x, T2 y)
{
cout << x << " " << y << endl;
}
int main()
{
int a = 1, b = 2;
double c = 1.00, d = 2.00;
cout << add(a, b) << endl; //隐式调用
cout << add(c, d) << endl;
cout << add<int>(a, b) << endl; //显示调用
print<int, double>(a, c);
cout << add<int>(a, c) << endl; //一定要显示调用
return 0;
}
函数模板定义形式template<typename T>
调用的形式
myswap<float>(a, b); //显示类型调用
myswap(a, b); //自动数据类型推导
函数模板和普通函数的对比:
- 函数模板不允许自动类型转化,普通函数可以进行自动类型转化。
- 函数模板可以像普通函数一样被重载
- c++编译器优先考虑普通函数
#include<iostream>
using namespace std;
void print(int a,int b)
{
cout<<"int"<<endl;
cout<<a<<" "<<b<<endl;
}
template<typename T1,typename T2>
void print(T1 a,T2 b)
{
cout<<"typename"<<endl;
cout<<a<<" "<<b<<endl;
}
template<typename T1,typename T2,typename T3>
void print(T1 a,T2 b,T3 c)
{
cout<<a<<" "<<b<<" "<<c<<endl;
}
int main()
{
int a=1,b=2,c=3;
print(a,b);//优先调用普通函数
print<int>(a,b);//函数模板
print(a,b,c);
return 0;
}
为什么要有类模板?
- 类模板用于实现类所需数据的类型参数化
- 类模板在表示如数组、表、图等数据结构显得特别重要,这些数据结构的表示和算法不受所包含的元素类型的影响
函数模板可以派生普通类和类模板
#include <iostream>
using namespace std;
template <typename T>
class A
{
protected:
T m_a;
public:
A(T a);
};
template <typename T>
A<T>::A(T a)
{
m_a = a;
}
class B : public A<int> //模板类派生普通类
{
private:
int m_b;
public:
B(int b);
};
B::B(int b) : A<int>(1) //显示调用
{
m_b = b;
}
template <typename T, typename T2>
class C : public A<T2> //派生模板类
{
private:
T m_c;
public:
C(T c, T2 a);
void print();
};
template <typename T, typename T2>
C<T, T2>::C(T c, T2 a) : A<T2>(a)
{
m_c = c;
}
int main()
{
B b(1);
C<int, double> c(1, 1.00);
return 0;
}
需要注意的是,类模板函数写在类的外部,友元函数重载<< >>时候类的前置声明,函数的前置声明,类的内部声明格式,
友元函数实现的格式以及函数调用格式
#include<iostream>
using namespace std;
template<typename T>
class A;
template<typename T>
ostream &operator<< (ostream &out,const A<T> &a);
template<typename T>
class A
{
private:
T m_a;
T m_b;
public:
A(int a,int b)
{
m_a=a;
m_b=b;
}
void print();
/*friend ostream operator<<(ostream out,const A &a)
{
out<<a.m_a<<"+"<<a.m_b<<"i"<<endl;
}*/
friend ostream &operator << <T>(ostream &out,const A &a);
};
template<typename T>
ostream &operator <<(ostream &out,const A<T> &a)
{
out<<a.m_a<<"+"<<a.m_b<<"i"<<endl;
return out;
}
template<typename T,typename T2>
class C:public A<T2>
{
private:
T m_c;
public:
C(T c,T2 a);
};
template<typename T,typename T2>
C<T,T2>::C<T c,T2 a>:A<T2>(a,a)
{
m_c=c;
}
template<typename T>
void A<T>::print()
{
cout<<m_a<<"+"<<m_b<<"i"<<endl;
}
int main()
{
A<int> a(1,2);
//a.print();
cout<<a;
C<int,double> c(1,1.1);
return 0;
}
所以最好把类模板写在类内部。