Vorlagen mit Standardparametern sind ein leistungsfähiger Mechanismus für generisches Programmieren in C++.
Geschichte der Frage:
Mit Vorlagen begann die STL-Bibliothek. Später wurde die Möglichkeit eingeführt, Standardwerte für Parameter sowohl von Vorlagenfunktionen als auch von -klassen anzugeben, um Vorlagen universeller zu gestalten und die Erweiterbarkeit des Codes zu unterstützen.
Problem:
Unklare Konflikte können auftreten, wenn sowohl Überladungen von normalen Funktionen als auch von Vorlagen vorhanden sind, sowie Mehrdeutigkeiten bei Spezialisierungen. Standardparameter in Vorlagen können die Flexibilität erhöhen, führen jedoch häufig zu verworrenen Kompilierungsfehlern.
Lösung:
Es ist besser, die Anzahl der Standardwerte in Vorlagen zu minimieren, insbesondere wenn es Überschneidungen mit den nicht-allgemeinen Versionen gibt. Bei Funktionsaufrufen hat die genaue Übereinstimmung mit der normalen Funktion Vorrang vor der Vorlage.
Beispielcode:
template<typename T = int> T multiply(T a, T b = T(2)) { return a * b; } int multiply(int a, int b) { return a + b; }
Der Aufruf multiply(5, 4) wählt die Funktion int multiply(int, int), während der Aufruf multiply<>(5) die Vorlage aufruft und b den Wert 2 annimmt.
Wichtige Merkmale:
Kann man Standardparameter in einer weiteren Definition einer Vorlagenfunktion deklarieren?
Nein, der Standardwert kann nur an einer Stelle angegeben werden (normalerweise in der Deklaration), andernfalls wird ein Kompilierungsfehler auftreten.
Was passiert bei Mehrdeutigkeit zwischen der Vorlage und der nicht-allgemeinen Funktion? Wie wählt der Compiler aus, was aufgerufen wird?
Der Compiler bevorzugt immer die nicht-allgemeine Funktion, wenn sie genau zu den Argumenten passt. Die Vorlage wird nur aufgerufen, wenn keine genaue Übereinstimmung vorliegt.
Kann man Standardwerte für einen nicht-typ Parameter der Vorlage angeben (z.B. für eine Zahl)?
Ja, zum Beispiel:
template<typename T, int N = 8> class Array { T data[N]; };
Negativer Fall
Sowohl die allgemeine als auch die nicht-allgemeine Funktion sind mit übereinstimmenden Parametern und Standardwerten deklariert. In einem Modul funktioniert der Aufruf wie vorgesehen, während in einem anderen unerwartet die falsche Version der Funktion ausgewählt wird.
Vorteile:
Nachteile:
Positiver Fall
Für überlappende Konfigurationen sind ausdrücklich unterschiedliche Bezeichnungen für allgemeine und nicht-allgemeine Funktionen eingeführt worden, wobei nur eine der Versionen Standardwerte hat.
Vorteile:
Nachteile: