Function Template Specialization
-
Ich habe gerade den Artikel Why Not Specialize Function Templates? gelesen und mit eigenen Beispielen etwas rumprobiert.
Dabei ist mir aufgefallen, dass folgende zwei Code Snippets, die bis auf die Reihenfolge der Funktionsdefinitionen gleich sind, unterschiedliche Outputs erzeugen (ein aehnliches Beispiel ist irgendwo im Artikel):// (a) template<typename T> void Foo( T ) { cout << "Base Foo" << endl; } // (b) template<typename T> void Foo( T* ) { cout << "Base Foo*" << endl; } // (c) template <> void Foo( int* ) { cout << "Specialization" << endl; } int main() { int i = 0; Foo( &i ); }Output: Specialization
// (a) template<typename T> void Foo( T ) { cout << "Base Foo" << endl; } // (c) template <> void Foo( int* ) { cout << "Specialization" << endl; } // (b) template<typename T> void Foo( T* ) { cout << "Base Foo*" << endl; } int main() { int i = 0; Foo( &i ); }Output: Base Foo*
Ich verstehe das so:
In 1) ist (c) eine Spezialisierung von (b). Beim Aufruf Foo( &i ) muss sich der Compiler zwischen (b) und (c) entscheiden. Da (c) die Spezialisierung von (b) ist wird (c) ausgefuehrt.
In 2) ist (c) eine Spezialisierung von (a). Beim Aufruf Foo( &i) hat der Compiler keine Wahl sondern muss (b) nehmen, da (b) eine Ueberladung von (a) ist, sich aber Spezialisierungen nicht ueberladen.Stimmt das so in etwa? Ich habe das ungute Gefuehl, dass das was ich geschrieben habe kreuzfalsch ist

Kann das jemand bestaetigen oder richtigstellen?
-
Also ich bin da auch nicht so 101% sattelfest, aber ich meine es müsste so sein...
In (1) ist (c) eine Spezialisierung von (b), soweit richtig.
D.h. Basis-Templates sind nur (a) und (b).
Der Compiler muss sich also erstmal nur zwischen (a) und (b) entscheiden. Denn Template-Spezialisierungen machen nicht bei der Overload-Resolution mit, immer nur die Basis-Templates. (Das steht auch im gotw Artikel)Also ist es T (a) vs. T* (b) und da gewinnt T* (b). Weil das halt besser passt.
Dann muss der Compiler das Template (b) instanzieren. Dazu guckt er ob es eine exakt passende Spezialisierung von (b) gibt, und - tadaa - es gibt eine, nämlich (c). Also nimmet er (c).
In (2) ist (c) eine Spezialisierung von (a). Soweit auch noch richtig.
Basis-Templates sind wieder nur (a) und (b).
Der Compiler muss sich wieder zwischen (a) und (b) entscheiden, und wieder gewinnt (b).Dann guckt der Compiler wieder ob es eine passende Spezialisierung gibt, und diesmal gibt es keine, also nimmt er das Basis-Template (b).
Falls du es so gemeint hast, OK, dann war es nur (für mich) unverständlich formuliert.
-
icarus2 schrieb:
Stimmt das so in etwa?
Ja.
-
@ hustbaer
Ja, ich hatte das in etwa so gemeint.Danke fuer eure Antworten!
-
Wer hat sich denn diese Regeln ausgedacht?

-
314159265358979__ schrieb:
Wer hat sich denn diese Regeln ausgedacht? 0:D
Das frag ich mich auch gerade (vielleicht aber aus anderen Gründen)... seit wann hängt das von der Reihenfolge der Funktionsdeklarationen (/definitionen?) ab?
-
Must du echt zu jedem meiner Posts deinen beknackten Senf abgeben?

GTFO!