Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / C++标准程序库 - 模板基础

本文是《C++标准程序库》模板相关内容的一个读书笔记,加上自己的一些理解和实践。 C++标准程序库:自修教程与参考手册 PDF中文版 下载 http://www.linuxidc.com/Linux/2013-07/87264.htm1.模板STL中大量使用模板以实现一个通用的工具库,比如STL提供了很多模板容器类别。模板(template)是为“一个或多个尚未明确的型别”所编写的函数或类别。使用模板时,可以显式(explicitly)或隐式(implicitly)地将型别当作参数来传递。有如下模板函数:
template <typename T>inline const T& max(const T& a, const T& b) {return a < b ? b : a;}
可做如下调用:
max<int>(1, 2);max(2, 3);
第一种方式是显式将型别作为参数传递给模板,第二种方式让编译器进行模板参数的自动推导,即模板参数的隐式传递。 2.模板的编译通常我们将一个类的声明和定义(实现)分别编写在.h文件和.cc文件中,但是模板的声明和实现都必须放在.h文件中才能编译通过。首先,要明确编译单元的概念。一个编译单元是指一个.cc文件和它所包含的所有.h文件,编译器将一个编译单元编译成一个.o文件。其次,模板并非一次编译就生成出适合所有型别的代码,而是针对被使用的某个(或某组)型别进行编译。这要求在编译模板时必须先知道它的某个实例,再针对这个实例编译出相应型别的模板代码。因此,如果我们将模板的声明和实现分别写在.h和.cc文件中,编译器在处理模板的.cc文件所代表的编译单元时,实际上是不会生成目标代码的,因为编译器没有被告知模板的任何一个实例。有如下分离的模板声明和实现:max_temp.h
ifndef MAX_TEMP_H_#define MAX_TEMP_H_ template <typename T>const T& max(const T& a, const T& b); #endif // MAX_TEMP_H_
 max_temp.cc
#include "max_temp.h" template <typename T>const T& max(const T& a, const T& b) {return a > b ? a : b;}
 编译模板并查看生成的.o文件中的符号表:
sw@gentoo ~ $ g++ -c max_temp.ccsw@gentoo ~ $ nm max_temp.osw@gentoo ~ $
可见max_temp.o中的符号表为空,即编译器并没有为模板生成任何目标代码。 如果将模板的声明和实现都放在.h文件中,并且在使用此模板的.cc文件中包含声明和实现此模板的.h文件,则编译器在处理此.cc文件时,将会得到模板的一个或多个实例,并且根据模板.h文件中的模板声明和实现为模板生成相应型别的代码。我们将上述示例代码作如下更改:max_temp.h
#ifndef MAX_TEMP_H_#define MAX_TEMP_H_ template <typename T>const T& max(const T& a, const T& b); #include "max_temp-inl.h" #endif // MAX_TEMP_H_
 max_temp-inl.h
#ifndef MAX_TEMP_INL_H_#define MAX_TEMP_INL_H_ template <typename T>const T& max(const T& a, const T& b) {return a > b ? a : b;} #endif // MAX_TEMP_INL_H_
 main.cc
#include "max_temp.h" int main(int argc, char* argv[]) {int m = max(1, 2);return 0;}
 编译main.cc并查看生成的.o文件中的符号表:
sw@gentoo ~ $ g++ -c main.ccsw@gentoo ~ $ nm main.o00000000 W _Z3maxIiERKT_S2_S2_00000000 T mainsw@gentoo ~ $
可以看到编译器为模板生成了目标代码。另外,在这个示例中,我们将模板的实现编写在-inl.h文件中,并且在声明模板的.h文件的末尾包含相应的-inl.h文件。这样可以像非模板类型一样将声明和实现分离,从而得到更优雅的代码。