歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++標准程序庫 - 模板基礎

C++標准程序庫 - 模板基礎

日期:2017/3/1 9:55:02   编辑:Linux編程

本文是《C++標准程序庫》模板相關內容的一個讀書筆記,加上自己的一些理解和實踐。

C++標准程序庫:自修教程與參考手冊 PDF中文版 下載 http://www.linuxidc.com/Linux/2013-07/87264.htm

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文件。這樣可以像非模板類型一樣將聲明和實現分離,從而得到更優雅的代碼。

Copyright © Linux教程網 All Rights Reserved