C++Vorlagen


Einführung

Klassen, Funktionen und (seit C ++ 14) Variablen können erstellt werden. Eine Vorlage ist ein Stück Code mit einigen freien Parametern, die zu einer konkreten Klasse, Funktion oder Variablen werden, wenn alle Parameter angegeben werden. Parameter können Typen, Werte oder selbst Vorlagen sein. Eine bekannte Vorlage ist std::vector , die zu einem konkreten Containertyp wird, wenn der Elementtyp angegeben wird, z. B. std::vector<int> .

Syntax

  • Deklaration der Vorlage < template-parameter-list >
  • exportiere die Deklaration < template-parameter-list > / * bis C ++ 11 * /
  • Deklaration der Vorlage <>
  • Template - Deklaration
  • extern Template - Deklaration / * da C ++ 11 * /
  • Template < Template-Parameter-List > Klasse ... ( Opt ) Bezeichner ( Opt )
  • template <template-Parameter-Liste> Klassenkennung (opt) = id-expression
  • template < template-parameter-list > typename ... ( opt ) Bezeichner ( opt ) / * seit C ++ 17 * /
  • template <template-Parameter-Liste> Typname Kennung (opt) = id-Ausdruck / * da C ++ 17 * /
  • Postfix-Ausdruck . Template- ID-Ausdruck
  • Postfix-Ausdruck -> Vorlagen- ID-Ausdruck
  • Nested-Name-Specifier- template simple-template-id ::

Bemerkungen

Die template ist ein Schlüsselwort mit fünf verschiedenen Bedeutungen in der C ++ - Sprache, je nach Kontext.

  1. Wenn eine Liste mit in <> eingeschlossenen Vorlagenparametern folgt, deklariert sie eine Vorlage, beispielsweise eine Klassenvorlage , eine Funktionsvorlage oder eine teilweise Spezialisierung einer vorhandenen Vorlage.

    template <class T>
    void increment(T& x) { ++x; }
    
  2. Wenn von einem leeren <> gefolgt wird, wird eine explizite (vollständige) Spezialisierung angegeben .

    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. Wenn eine Deklaration ohne <> folgt, bildet sie eine explizite Instantiierungsdeklaration oder -definition.

    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. Innerhalb einer Vorlage Parameterliste, führt sie einen Template - Template - Parameter .

    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. Nach dem Bereichsauflösungsoperator :: und den Klassenmitgliedszugriffsoperatoren . und -> gibt an, dass der folgende Name eine Vorlage ist.

    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
        }
    };
    

Vor C ++ 11 konnte eine Vorlage mit dem export deklariert werden , um daraus eine exportierte Vorlage zu machen. Die Definition einer exportierten Vorlage muss nicht in jeder Übersetzungseinheit vorhanden sein, in der die Vorlage instanziiert wird. Zum Beispiel sollte folgendes funktionieren:

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
}

Aufgrund von Schwierigkeiten bei der Implementierung wurde das export von den meisten großen Compilern nicht unterstützt. Es wurde in C ++ 11 entfernt. Das export Schlüsselwort darf jetzt überhaupt nicht verwendet werden. Stattdessen müssen in der Regel Vorlagen in Kopfzeilen definiert werden (im Gegensatz zu Funktionen, die keine Vorlagen sind und normalerweise nicht in Kopfzeilen definiert sind). Siehe Warum können Vorlagen nur in der Headerdatei implementiert werden?

Vorlagen Verwandte Beispiele