一个是类型参数,一个是非类型参数
template<typename T, int i>
class Buffer
{ T v[i];
int sz;
public:
Buffer():sz(i) { }
…
};
Buffer<char,127> cbuf;
Buffer<Record,8> rbuf;
!!!模板参数必须是常量
•Example:void f(int i)
{
Buffer<int,i> bx; // Error
}
函数模板:
例子:
template<typename T>
void Swap(T& x,T& y)
{
T temp=x; x=y; y=temp;
}
template<typename T, typename Compare = std::less<T>>
void Sort(vector<T>& v)
{
Compare cmp; // make a default Compare object
const size_t n = v.size();
for (int gap=n/2; 0<gap; gap/=2)
for (int i=gap; i<n; i++)
for (int j=i-gap; 0<=j; j-=gap)
if (cmp(v[j+gap],v[j]))
Swap(v[j],v[j+gap]);//希尔排序
}
struct No_case
{
bool operator()(const string& a, const string& b) const;
// compare case insensitive
};
函数模板和函数模板重载问题:
template<typename T>
T sqrt(T);
template<typename T>
complex<T> sqrt(complex<T>);
double sqrt(double);
void f (complex<double> z)
{
sqrt(2); // sqrt<int>(int)
sqrt(2.0); // sqrt(double)
sqrt(z); // sqrt<double>(complex<double>)(特例化)
}
没有类型转换的普通函数优先级较高。
二异性错误:
template<typename T> T max(T, T);
const int s = 7;
void k()
{
max(1,2); // max<int>(1,2)
max('a','b’); // max<char>(’a’,’b’)
max(2.7,4.9); // max<double>(2.7,4.9)
max(s,7); // max<int>(int{s},7) (trivial conversion used)
max('a',1);
// error : ambiguous: max<char,char>() or max<int,int>()?
max(2.7,4);
// error : ambiguous: max<double,double>() or max<int,int>()?
}
如果要调用就是显式调用 例如:max<int>('a',1)
specilation:
默认情况下,模板提供用于每个模板参数的单个定义 - 泛化。 也可以为特殊模板参数提供替代定义。这些定义称为用户专用化。
例子:
template<typename T>
class Vector {
T* v; int sz;
public:
Vector();
explicit Vector(int);
T& elem(int);
T& operator[](int);
…
};
由于所有指针类型导致代码膨胀,最好使所有指针共享一个专用化。
// specialization for argument type void*
template<> class Vector<void*> {//完全特例化
void** p; int sz;
public:
Vector();
explicit Vector(int);
void*& elem(int);
void*& operator[](int);
…
};
// specializtion for any pointer argument
template<typename T> class Vector<T*>
: private Vector<void*> {//部分特例化
public:
typedef Vector<void*> Base;
Vector():Base() { }
explicit Vector(int i):Base(i){}
T*& elem(int i) { return static_cast<T*&>(Base::elem(i));}
T*& operator[](int i)
{ return static_cast<T*&>(Base::operator[](i));}
…
};
特例化其实就是为了减少代码膨胀
如果在通用模板使用很多数据类型,处理起来就比较泛泛.
特例化的定义必须在使用之前
template<typename T> class List;
// declare before any specializations
List<int*> li; // error
template<typename T>
class List<T*>
{…};
一个特例化
template<typename T> class List;
// declare before any specializations
List<int*> li; // error
template<typename T>
class List<T*>
{…};