学习笔记:C++ template的使用

template 模板:


template

  • 学习笔记:C++ template的使用
  • 为什么需要类模板
  • typename和class:
  • 总结:



C++提供了模板(template)编程的概念。所谓模板,实际上是建立一个通用函数或类,其类内部的类型和函数的形参类型不具体指定,用一个虚拟的类型来代表。这种通用的方式称为模板。模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。


为什么需要类模板

类模板与函数模板的定义和使用类似,有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,我们可以通过如下面语句声明了一个类模板:

template <typename T>
class A
{
public:
	A(T t){
		this->t = t;
	}
 
	T& getT(){
		return t;
	}
 
public:
	T t;
};

typename和class:

在模板类的声明中,我们有两种方式::

template <class T>
template <typename T>

在这里,class和typename是相同的。也就是说,在声明一个template type parameter(模板类型参数)的时候,class和typename意味着
完全相同的东西。

但是,在C++中,有的时候必须要使用typename.下面我们列举下面一个例子。

关键字typename被用来作为型别之前的标识符号。

template <class T>
class MyClass{
    typename T::SubType * ptr;
    ...
};

在这里,typename指出SubType是class T中定义的一个类别,因此ptr是一个指向T::SubType型别的指针。如果没有关键字typename,SubType会被当成一个static成员,于是T::SubType * ptr,会被解释为型别T内的数值SubType与ptr的乘积.

SubType成为一个型别的条件是,任何一个用来取代T的型别,其内部必须有一个内部型别(inner type)SubType的定义。例如,将型别Q当作template的参数。
MyClass" x;"

必要条件是型别Q有如下的内部型别定义:

class Q{
    typedef int SubType;
    ...
};

因此,MyClass"的ptr成员应该变成一个指向int型别的指针,子型别SubType也可以成为抽象
数据型别(例如,class):"

class Q{
    class SubType;
    ...
};

注意,如果要把一个template中的某个标识符号指定为一种类别,就算是意图显而易见,关键字typename也是不能省略的,因此C++的一般规则是,除了使用typename修饰之外,template内的任何标识符号都被视为一个值而不是一个类别(对象)。

总结:

template<typename T>与template<class T>一般情况下这两个通用,但有一个特例,就是当 T 是一个类,而这个类又有子类(假设名为 innerClass) 时,应该用 template<typename>:
typename T::innerClass myInnerObject;这里的 typename 告诉编译器,T::innerClass 是一个类,程序要声明一个 T::innerClass 类的对象,而不是声明 T 的静态成员,而 typename 如果换成 class 则语法错误。