模板
template
這個詞是一個關鍵詞 ,在 C++語言中有五種不同的含義,具體取決於上下文。
-
當後面跟著
<>
中包含的模板引數列表時,它會宣告一個模板,例如類别範本 ,函式模板或現有模板的部分特化。template <class T> void increment(T& x) { ++x; }
-
當後面跟著一個空的
<>
時,它會宣告一個顯式(完整)特化 。template <class T> void print(T x); template <> // <-- keyword used in this sense here void print(const char* s) { // output the content of the string printf("%s\n", s); }
-
當後面跟不帶
<>
的宣告時,它形成一個顯式的例項化宣告或定義。template <class T> std::set<T> make_singleton(T x) { return std::set<T>(x); } template std::set<int> make_singleton(int x); // <-- keyword used in this sense here
-
在模板引數列表中,它引入了模板模板引數 。
template <class T, template <class U> class Alloc> // ^^^^^^^^ keyword used in this sense here class List { struct Node { T value; Node* next; }; Alloc<Node> allocator; Node* allocate_node() { return allocator.allocate(sizeof(T)); } // ... };
-
在範圍解析運算子
::
和類成員訪問運算子.
和->
之後,它指定以下名稱是模板。struct Allocator { template <class T> T* allocate(); }; template <class T, class Alloc> class List { struct Node { T value; Node* next; } Alloc allocator; Node* allocate_node() { // return allocator.allocate<Node>(); // error: < and > are interpreted as // comparison operators return allocator.template allocate<Node>(); // ok; allocate is a template // ^^^^^^^^ keyword used in this sense here } };
在 C++ 11 之前,可以使用 export
關鍵字宣告模板,使其成為匯出的模板。匯出模板的定義不需要出現在例項化模板的每個轉換單元中。例如,以下應該起作用:
foo.h
:
#ifndef FOO_H
#define FOO_H
export template <class T> T identity(T x);
#endif
foo.cpp
:
#include "foo.h"
template <class T> T identity(T x) { return x; }
main.cpp
:
#include "foo.h"
int main() {
const int x = identity(42); // x is 42
}
由於實施困難,大多數主要編譯器都不支援 export
關鍵字。它在 C++ 11 中刪除了; 現在,完全使用 export
關鍵字是違法的。相反,通常需要在標頭檔案中定義模板(與非模板函式相反,非模板函式通常不在標頭檔案中定義)。請參閱為什麼模板只能在標頭檔案中實現?