C++模板
模板有类模板,函数模板和成员模板。
类模板
template <typename T>
class complex
{
public:
complex(T r = 0, T i = 0)
:re(r), im(i) {}
T real() const { return re; }
T imag() const { return im; }
private:
T re, im;
};
{
complex<double> c1(2.5, 1.5);//在使用 complex 模板时要通过`<>` 明白的告诉编译器,我现在的 T 是什么样的类型。
complex<int> c2(2, 6);
}
函数模板
template <class T>
inline
const T& _min(const T& a, const T& b)
{
return b < a ? b : a;
}
class stone
{
public:
stone(int w, int h, int we)
:_w(w), _h(h), _weight(we) {};
bool operator< (const stone& rhs) const
{
return _weight < rhs._weight;
}
private:
int _w, _h, _weight;
};
{
//基本类型是用函数模板
_min(1, 3);
_min(1.5, 3.7);
//自定义数据使用函数模板
stone r1(2, 3, 5), r2(3, 3, 3);
_min(r1, r2);
}
编译器会根据编写的语法代码,去寻找指定的模块代码。
比如,调用了_min
编译器就会去寻找_min
相关的符号链接。然后就找到了 _min
的函数。
在 b < a ? b : a;
中 因为 T 是自定义类型,所以又会去找相应的符号重载。于是,就调用 stone 的 operator<
函数。
类模板中的全特化和偏特化
全特化
全特化也称为泛化
参数的偏特化
根据传入参数的个数不同,调用不同的类模板。偏特化的类模板会比全特化的类模板或许会有空间效率方面的提升。
// CLASS TEMPLATE vector
template<class _Ty,
class _Alloc = allocator<_Ty>>
class vector
: public _Vector_alloc<_Vec_base_types<_Ty, _Alloc>>
{};
// CLASS vector<bool>
template<class _Alloc>
class vector<bool, _Alloc>
: public _Vb_val<_Alloc>
{};
范围的偏特化
template <class Iterator>
struct interator_traits{ //泛化
void foo(Iterator a)
{
cout << a << "泛化" << endl;
}
};
template <class T>
struct interator_traits<T*>//偏特化 有独特的设计,根据使用者传入的内容的变化而调用不同的类模板
{
void foo(T* pa)
{
cout << *pa << "偏特化" << endl;
}
};
/*
如果我传入的是一个指针,则调用特化的类模板
如果我传入的不是一个指针,则调用泛化的类模板
*/
void PartialSpecialization()
{
interator_traits<int> T;
T.foo(1);
interator_traits<int*> PT;
int a = 4;
PT.foo(&a);
}
成员模板
参考:《C++ STL与泛型编程》