Ich habe versucht, ein prägnantes Zitat aus dem Standard zu finden, aber ich denke nicht th Es ist einer. Tatsache ist, dass es keine partielle Spezialisierung einer Template-Funktion (oder, in der Tat, eines Template-Alias) gibt. Nur Klassenvorlagen können teilweise spezialisiert sein.
Lassen Sie uns für eine Sekunde die Vorlagen vergessen. In C++ gibt es einen großen Unterschied zwischen Klassennamen und Funktionsnamen. Es kann nur eine Definition einer Klasse innerhalb eines bestimmten Bereichs geben. (Sie können verschiedene Deklarationen haben, aber sie beziehen sich alle auf die eine wahre Klasse.) Der Name identifiziert die Klasse also wirklich.
Ein Funktionsname ist andererseits eine Art Gruppenidentität. Sie können beliebig viele Funktionen innerhalb eines Bereichs mit exakt demselben Namen definieren. Wenn Sie einen Funktionsnamen verwenden, um eine Funktion aufzurufen, muss der Compiler herausfinden, welche Funktion Sie wirklich verstanden haben, indem Sie die verschiedenen Möglichkeiten betrachten und die Signatur jedes einzelnen mit den angegebenen Argumenten abgleichen. Es gibt keine Beziehung zwischen den verschiedenen Funktionen, die einen Namen teilen; Sie sind völlig separate Entitäten.
Also, keine große Sache. Du wusstest das alles, oder? Aber jetzt gehen wir zurück zu Vorlagen.
Der Name einer Vorlagenklasse ist immer noch einzigartig.Obwohl Sie teilweise Spezialisierungen definieren können, müssen Sie die gleiche Template-Klasse explizit spezialisieren. Dieser Mechanismus sieht oberflächlich aus wie der Algorithmus zur Auflösung von Funktionsnamen, auf den oben Bezug genommen wurde, aber es gibt signifikante Unterschiede. Einer davon ist, dass Sie im Gegensatz zu Funktionsprototypen nicht zwei Klassenvorlagen mit verschiedenen Arten von Vorlagenparametern haben können.
Für Vorlagenfunktionen müssen dagegen keine eindeutigen Namen definiert werden. Templating ersetzt nicht den normalen Funktionsüberlastungsmechanismus. Wenn der Compiler also versucht herauszufinden, was ein Funktionsname bedeutet, muss er alle deklarierten Deklarationen für diesen Funktionsnamen berücksichtigen, die Vorlagen in eine Menge von Vorlagenparametern (wenn möglich) auflösen und dann einmal hat eine Liste von möglichen Funktionsobjekten, wählen Sie das beste mit normaler Überladungsauflösung.
Das ist ein ganz anderer Algorithmus als die Template-Parameterauflösung mit Templaten. Anstatt nur eine Liste der bereitgestellten Template-Argumente mit einer Liste von deklarierten Template-Parametern zu vergleichen, wie sie Klassen-Templates auflöst, muss sie jede Template-Funktion übernehmen, die möglicherweise übereinstimmt (hat zum Beispiel mindestens die richtige Anzahl von Parametern) ; abzuleiten Template-Parameter durch Vereinheitlichung der gelieferten Argumente mit der Vorlage; und fügen Sie dann die Auflösungsspezialisierung zur Überladungsgruppe für eine weitere Runde der Überladungsauflösung hinzu.
Ich denke, es wäre möglich gewesen, auch in diesem Prozess eine teilweise Spezialisierungsauflösung hinzuzufügen, aber die Interaktionen zwischen partieller Spezialisierung und Funktionsüberlastung erscheinen mir wahrscheinlich zu einem pseudo-magischen Verhalten. In diesem Fall war es nicht notwendig und daher gibt es keinen solchen Mechanismus. (Sie können eine Funktionsvorlage vollständig spezialisieren. Vollständige Spezialisierung bedeutet, dass keine Argumente für die Vorlage abgeleitet werden können.)
Also das ist der Scoop: Sie können eine Vorlagenfunktion nicht teilweise spezialisieren, aber es gibt sie nichts hält Sie davon ab, eine beliebige Anzahl von Funktionsvorlagen mit dem gleichen Namen bereitzustellen. Alle von ihnen werden in Überladungsauflösung betrachtet, und der Beste wird wie üblich gewinnen.
Normalerweise ist das für Ihre Überlastungsbedürfnisse tatsächlich ausreichend. Sie sollten über Vorlagenfunktionen genau so nachdenken, wie Sie über normale Funktionen denken: Sie haben die Möglichkeit, basierend auf den angegebenen Argumenten die gewünschte Vorlage auszuwählen. Wenn Sie der Meinung sind, dass Sie Template-Parameter in einem Funktionsaufruf angeben müssen, anstatt sie abzuleiten, machen Sie einfach die Funktion zu einem (möglicherweise statischen) Mitglied einer Template-Klasse und geben Sie die Template-Argumente an die Klasse weiter.
Hoffnung, dass ...
Fast doppelt: http://stackoverflow.com/questions/12335762/partial-specialization-of-member-function und http://stackoverflow.com/questions/165101/invalid-use-of-incomplete-type- Fehler-mit-Teil-Template-Spezialisierung. – jogojapan