"Vorlage <>" vs "Vorlage" ohne Klammern - was ist der Unterschied?

77

Angenommen, ich habe erklärt:

template <typename T> void foo(T& t);

Was ist nun der Unterschied zwischen

template <> void foo<int>(int& t);

und

template void foo<int>(int& t);

semantisch? Und haben Vorlagen ohne Klammern und Vorlagen mit leeren Klammern in anderen Kontexten eine andere Semantik?


Verwandte Themen: Wie erzwinge ich die Instanziierung einer bestimmten Instanz einer C ++ - Vorlage?

einpoklum
quelle

Antworten:

70

template <> void foo<int>(int& t);deklariert eine Spezialisierung der Vorlage mit möglicherweise unterschiedlichem Text.

template void foo<int>(int& t);bewirkt eine explizite Instanziierung der Vorlage, führt jedoch keine Spezialisierung ein. Es wird lediglich die Instanziierung der Vorlage für einen bestimmten Typ erzwungen.

Mark B.
quelle
3
Das ist ziemlich verwirrend! Ich gehe davon aus, dass die Bedeutung der Deklaration darin besteht, dass der Compiler die Instanziierung der nicht spezialisierten Vorlage als Kandidat nicht akzeptiert, wenn die spezialisierte Definition nicht gefunden wird.
Einpoklum
3
Erklären Sie dies etwas genauer: Die erste kann in einer Header-Datei verwendet werden und lautet " foo<int>wird einen anderen Körper haben als foo<T>"; Wenn Code an anderer Stelle im Programm foo<int>()aufgerufen wird, Sie den Text jedoch nicht angeben, sollte ein Alink-Fehler angezeigt werden.
MM
4
Die zweite sollte nicht in einer Header-Datei verwendet werden. Wenn Sie es in einer CPP-Datei verwenden, wird sichergestellt, dass der Hauptteil von foo<int>(der die foo<T>Vorlage zum Generieren verwendet, es sei denn, Sie hatten auch die Spezialisierungszeile!) tatsächlich verarbeitet wird (ähnlich wie beim Definieren einer Nicht-Vorlagenfunktion). Normalerweise müssen Sie dies nicht tun, da es passiert, wenn ein anderer Code aufruft foo<int>, aber Sie möchten es vielleicht aus ein paar Gründen
MM
Es ist weniger verwirrend, wenn Sie das <> als Sonderfall einer leeren Vorlagenparameterliste sehen. Im Allgemeinen verwenden Sie diese Syntax, um ( möglicherweise teilweise ) Spezialisierungen zu erstellen . Wenn es keine Parameter hat (dh nicht partiell), erhalten Sie diese Syntax. Sie deklarieren immer noch eine Vorlage .
JDługosz
@jdlugosz: Ich hatte den Eindruck, dass eine teilweise Spezialisierung nicht unterstützt wird ...
einpoklum
13

Mit Klasse / Struktur,

template <typename T> struct foo {};

Es folgt eine Spezialisierung:

template <> struct foo<int>{};

Es folgt eine explizite Instanziierung:

template struct foo<int>;
Jarod42
quelle