模板可能是c++中最强大最强大却最少被使用(或被理解)的特性之一了;我们可以用模板来定义一种适用于不同类型的对象的行为
这就像是用#define定义的一个返回两个数中最大值的宏函数那样
#define MAX_NUM(a, b) ((a) > (b) ? (a) : (b))
这里的a,b可以是int类型、也可以是其他类型;与“”宏函数不同的是宏不是类型安全的,而模板是类型安全的

  • 模板函数/类声明语法
1
2
template <参数列表>   
模板函数/类的声明

参数列表中包含关键字typename,它定义了参数objectTyep,objectType是一个占位符,当对象实例化模板时(创建类实例时)将使用指定的对象类型替换它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//模板函数   
template <typename T>
const T& GetMax(const T& num1, const T& num2)
{
if(num1 < num2)
return num2;
return num1;
}

//模板类
template <typename T1, typename T2>
class Template
{
private:
T1 m_Obj1;
T2 m_Obj2;
public:
Template(T1 obj1, T2 obj2):
m_Obj1(obj1), m_Obj2(obj2){ }

void print(){
cout << m_Obj1 << " " << m_Obj2 << endl;
}
};

int main()
{
Template<int, float> tem(66, 66.6);
tem.print();
cout << GetMax<float>(25.5, 123) << endl;
cout << GetMax(25.5, 123.0)
return 0;
}

上述代码中实例化Template类时,将T1指定为int类型,将T2指定为float类型(显式指定)。
第一次调用模板函数时,将T指定为float类型;第二次调用时却没有指定类型,但这样也是正确的,这时候,模板函数会自动判断数据的类型(隐式指定)。
不过,对于模板类,必须要显式指定其类型

声明包含多个参数的模板
声明包含多个参数的模板时, 参数之间用逗号隔开:
template < typename T1, typename T2,...., typename Tn >

声明包含默认参数的模板
声明包含默认参数的模板时, 可将它初始化成默认类型:
template < typename T1 = int, ... , typename tn = int >

*模板类和静态成员
在普通的类中,类成员被定义成静态的话,该静态成员被所有实例共享;
在模板类中,也类似这样,只不过是被同类型的具体化的实例所共享的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
template <typename T>
class Template
{
private:
T m_Obj1;
static int T_Num;
public:
static int getT_Num()
{
return T_Num;
}
static void setT_Num(const int& num)
{
T_Num = num;
}
};

//静态成员变量的初始化
template <typename T>
int Template<T>::T_Num = 0;


int main()
{
Template<int>::setT_Num(1997);
Template<float>::setT_Num(917);
cout << Template<int>::getT_Num() << endl; //1997
cout << Template<float>::getT_Num() << endl; //917
return 0;
}

上述代码中两次输出结果分别是1997、917。你该懂了吧
c++中的静态成员变量
在c++的类中,如果存在静态成员变量的话,必须对它进行初始化,格式如下:
<数据类型><类名>::<静态数据成员名> = <值>

模板类中的静态成员变量的初始化格式:(参考上述代码的初始化)
template<参数> <数据类型><类名<参数>>::<静态数据成员名> = <值>

c++11
使用static_assert执行编译阶段的检查(类似assert宏)
static_assert是c++11中新加的功能(有的编译器不支持),它是一种编译断言,能够在不满足条件时禁止编译。使用格式:
static _assert(表达式, "表达式为假时输出的错误信息")

1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
class CanNotInt
{
public:
CanNotInt(){
static_assert(sizeof(T) != sizeof(int), "No int please");
}
};
int main()
{
CanNotInt<int> test;
return 0;
}

上述代码编译时会报错。


 上一页

C++ STL

 评论