模板

template 這個詞是一個關鍵詞 ,在 C++語言中有五種不同的含義,具體取決於上下文。

  1. 當後面跟著 <> 中包含的模板引數列表時,它會宣告一個模板,例如類别範本函式模板或現有模板的部分特化。

    template <class T>
    void increment(T& x) { ++x; }
    
  2. 當後面跟著一個空的 <> 時,它會宣告一個顯式(完整)特化

    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);
    }
    
  3. 當後面跟不帶 <> 的宣告時,它形成一個顯式的例項化宣告或定義。

    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
    
  4. 在模板引數列表中,它引入了模板模板引數

    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));
        }
        // ...
    };
    
  5. 在範圍解析運算子::和類成員訪問運算子 .-> 之後,它指定以下名稱是模板。

    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 關鍵字是違法的。相反,通常需要在標頭檔案中定義模板(與非模板函式相反,非模板函式通常不在標頭檔案中定義)。請參閱為什麼模板只能在標頭檔案中實現?