模版简介
模板是 C++ 中的泛型编程的基础。 作为强类型语言,C++ 要求所有变量都具有特定类型,由程序员显式声明或编译器推导。 但是,许多数据结构和算法无论在哪种类型上操作,看起来都是相同的。 使用模板可以定义类或函数的操作,并让用户指定这些操作应处理的具体类型。
定义和使用模板
模板是基于用户为模板参数提供的参数在编译时生成普通类型或函数的构造。 例如,可以定义如下所示的函数模板:
template <typename T> |
上面的代码描述了一个具有单个类型参数 T 的泛型函数的模板,其返回值和调用参数(lhs 和 rhs)都具有此类型。 可以随意命名类型参数,但按照约定,最常使用单个大写字母。 T 是模板参数;关键字 typename
表示此参数是类型的占位符。 调用函数时,编译器会将每个 T 实例替换为由用户指定或编译器推导的具体类型参数。 编译器从模板生成类或函数的过程称为“模板实例化”;minimum<int>
是模板 minimum<T>
的实例化。
在其他地方,用户可以声明专用于 int 的模板实例。假设 get_a() 和 get_b() 是返回 int 的函数:
int a = get_a(); |
但是,由于这是一个函数模板,编译器可以从参数 a 和 b 中推导出类型,因此可以像普通函数一样调用它:T
int i = minimum(a, b); |
当编译器遇到最后一个语句时,它会生成一个新函数,在该函数中,T 在模板中的每个匹配项都替换为 int
:
int minimum(const int& lhs, const int& rhs) |
类型参数
在上面的 minimum
模板中,请注意,在将类型参数 T 用于函数调用参数(在这些参数中会添加 const 和引用限定符)之前,不会以任何方式对其进行限定。
类型参数的数量没有实际限制。 以逗号分隔多个参数:
template <typename T, typename U, typename V> class Foo{}; |
在此上下文中,关键字 class 等效于 typename。 可以将前面的示例表示为:
template <class T, class U, class V> class Foo{}; |
可以使用省略号运算符 (…) 定义采用任意数量的零个或多个类型参数的模板:
template<typename... Arguments> class vtclass; |
任何内置类型或用户定义的类型都可以用作类型参数。 例如,可以使用标准库中的 std::vector 来存储类型 int、double、std::string、MyClass、const、MyClass*、MyClass& 等的变量。 使用模板时的主要限制是类型参数必须支持应用于类型参数的任何操作。 例如,如果我们使用 MyClass 调用 minimum,如以下示例所示:
class MyClass |
参考
[1] 模板(C++)