4 Stimmen

Warum Template-Spezialisierungen verwenden?

Ich frage mich, warum Template-Spezialisierungen sinnvoll sind?

Sind die folgenden Dinge nicht gleichwertig?

Template-Spezialisierung:

template <typename T>
void f(T t) {
  something(t);
}

template <>
void f<int>(int t) {
  somethingelse(t);
}

Nicht-Template-Funktion anstelle von Spezialisierung:

void f(int t) {
  somethingelse(t);
}

Ich glaube, dass diese gleich sind, weil die Nicht-Template-Funktion immer bevorzugt wird.

4voto

Sarien Punkte 6302

Das ist die Antwort, die ich mir ausgedacht habe:

Es ist anders, wenn der Vorlagenparameter nicht ein Parameter der definierten Funktion ist:

template 
void f() {
  T t;
  etwas(t);
}

template <>
void f() {
  int t;
  etwasanderes(t);
}

In diesem Fall würde die Definition:

void f() {
  int t;
  etwasanderes(t);
}

alle Vorlagenversionen unbenutzbar machen.

Vielleicht hat jemand anderes bessere Ideen. :)

3voto

Bo Persson Punkte 88207

Der Weg, wie Sie die Funktion deklarieren, spielt eine Rolle, wenn Sie darauf bestehen, sie wie f(42) aufzurufen. Dies findet die Spezialisierung, aber nicht die Überladung.

Wenn der Aufruf immer wie f(42) aussieht, wird jede Alternative funktionieren.

3voto

Diese Frage läuft darauf hinaus, zu bestimmen, wann die Spezialisierung verwendet werden soll, die die Überlastung nicht kann. Es gibt verschiedene Situationen, in denen dies der Fall ist, obwohl sie selten genug sind und es einfach genug ist, Fehler zu machen, dass die allgemeine Empfehlung darin besteht, Überlastungen Spezialisierungen vorzuziehen.

  • Wenn der Aufrufer explizit die Verwendung einer Vorlage anfordert. Im von Ihnen bereitgestellten Codebeispiel wird die Überlastung nicht verwendet, wenn der Aufruf f(42) oder sogar f<42>() lautet.

  • Wenn Sie die erforderlichen Überlastungen nicht bereitstellen können oder die Überlastung an der Stelle des Aufrufs nicht aufgelöst werden kann. Zum Beispiel, wenn der Typ nicht einer der Funktionsargumente ist (entweder gar nicht in der Signatur vorhanden ist oder nur im Rückgabetyp:

    template T f();

In diesem Fall können Sie die Überladungen int f(); und double f(); nicht bereitstellen, aber Sie können so viele Vorlagenspezialisierungen bereitstellen, wie Sie benötigen, und es liegt am Benutzer, die Auswahl von einer oder der anderen zu erzwingen. Beachten Sie, dass dies als ein Unterfall des vorherigen Falls betrachtet werden könnte: Da die Vorlagensargumente keinen Teil der Funktionsargumente bilden, muss der Benutzer die Vorlagensargumente bereitstellen, damit der Aufruf explizit einer Vorlage zuzuordnen ist.

  • Wenn Sie spezielle Einschränkungen für die Kombination der Argumente festlegen und implizite Konvertierungen unterbinden möchten:

    template void f( T, T ); // Beide Argumente müssen denselben Typ sein

Weil die Vorlagennargumentdeduktion nur perfekte Übereinstimmungen durchführt, kann diese Vorlage nur verwendet werden, wenn beide Argumente genau vom gleichen Typ sind. Wenn Sie eine Überladung hinzufügen void f(int,int), kann diese Überladung mit jeder Kombination von Typen verwendet werden, die implizit in int konvertierbar sind, wie f( 5, 3.0 ), aber die Spezialisierung wird nicht verwendet.

Im Allgemeinen treffen in den meisten Fällen keiner der oben genannten Fälle wirklich zu, daher sollte eine Überladung bevorzugt werden.


Es gibt möglicherweise noch mehr, aber das sind diejenigen, an die ich mich spontan erinnern kann

0voto

Dirk Holsopple Punkte 8641

Die Spezialisierung von Funktionsvorlagen wird zugunsten von Funktionsüberladungen abgelehnt, mit einer Ausnahme: Sie dürfen eine Funktionsvorlagen-Spezialisierung dem std-Namespace hinzufügen, jedoch keine neue Funktion hinzufügen. Wenn Sie also eine spezifische Version für etwas im std-Namespace bereitstellen müssen, müssen Sie eine Vorlagenspezialisierung verwenden. Beispielsweise müssen Sie std::hash für Ihre Klasse spezialisieren, um die Erstellung einer unordered_map mit einer benutzerdefinierten Klasse als Schlüssel zu unterstützen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X