1、Function Templates(函数模版)
例:
tempalte <typename T>
T GetMax(T a, T b)
{
return a < b ? b : a;
}
/// 重载
tempalte <typename T>
T GetMax(T a, T b, T c)
{
return (c < GetMax(a, b) ? GetMax(a, b) : c);
}
/// 默认类型
template <typename T=int>
T GetMax(T a, T b)
{
retrun a < b ? b : a;
}
2、Class Templates(类模版)
例:
template <typename T>
class MyStack
{
friend class CFriend1; // 普通友元类不需要先申明
friend class CFriend2<T>; // error, 友元模板类必须先申明
public:
void Push(T const&);
void Pop();
T Top() const;
bool Empty() const;
private:
std::vector<T> elems;
};
void MyStack<T>::Push(T const& e)
{
elems.push_back(e);
}
/// 继承
template <typename T>
class Derived : public MyStack<T>
{
public:
void Test()
{
Top(); // 应该使用this->Top() 或 MyStack<T>::Top(), 否则就调用外部Top(),或者编译错误
}
/// 成员模版函数,不能是virtual
template <typename T2>
void Test2()
{
}
};
3、NonType Templates(非类型模版参数)
局限性:通常只能是常数整数(包括enum)和指向局部变量的指针。
例:
template <typename T, int MAXSIZE>
struct NonTypeStruct
{
T elems[MAXSIZE];
};
4、typename 关键字
typename是在C++标准化工程中被引入的,目的是向编译器说明template内部的某个表示符号是个类型。
例:
template<typename T>
struct MyStruct
{
typename T::SubType* m_Ptr; // 表示m_Ptr是指向SubType是T内部类型的一个指针,若没有typename,就表
示T的静态变量SubType乘以m_Ptr。
};
5、双重模版参数
例:
template <typename T, template <typename> class CT>
class DoubleTemplate
{
CT<t> m_ct;
};
DoubleTemplate<int, std::vector> dbTemplate; // 类中定义了一个vector<int>的成员属性m_ct;
6、模板的申明和定义必须在同一个文档中,否则会出现连接错误
例:
// Test.h
template <typename T>
T Max(T a);
// Test.cpp
template <typename T>
T Max(T a) { return a; }
// Main.cpp
#include "Test.h"
void main()
{
int a = Max<int>(1); // error LNK2019,除非同时 #inclde "test.cpp"
}
7、模版类不能和其它不同类型的实体同名。
例:
int c;
class c; // ok,普通类可以
template <typename T>
class c; // error,模板类不行
8、在类中声明友元模版类
例:
class Manager
{
template <typename T>
friend class Task;
};
9、看看小细节
例:
template <bool b>
class Invert
{
public:
static bool const result = !b;
};
bool bTest = Invert<(1>0)>::result; // (1>0)小括号必须存在
std::vector<std::list<int> > vectList; // <std::list<int> >空格必须存在