C++标准程序库 - 模板基础


本文是《C++标准程序库》模板相关内容的一个读书笔记,加上自己的一些理解和实践。 

C++标准程序库:自修教程与参考手册 PDF中文版 下载

1.模板

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.cc

sw@gentoo ~ $ nm max_temp.o

sw@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.cc

sw@gentoo ~ $ nm main.o

00000000 W _Z3maxIiERKT_S2_S2_

00000000 T main

sw@gentoo ~ $

可以看到编译器为模板生成了目标代码。

另外,在这个示例中,我们将模板的实现编写在-inl.h文件中,并且在声明模板的.h文件的末尾包含相应的-inl.h文件。这样可以像非模板类型一样将声明和实现分离,从而得到更优雅的代码。

  • 1
  • 2
  • 下一页

相关内容

    暂无相关文章