Ohne Instanziierung wird der Vorlagencode selbst auf Syntax überprüft.
ZB: Alle Syntaxfehler wie ;etc.
Zum Zeitpunkt der Instanziierung (wenn der genaue Typ bekannt ist) wird der Vorlagencode erneut überprüft, um sicherzustellen, dass alle Aufrufe für diesen bestimmten Typ gültig sind.
Beispiel: Die Vorlage ruft möglicherweise Funktionen auf, die für diesen bestimmten Typ möglicherweise nicht vorhanden sind.
Beachten Sie auch, dass die Suche nach nicht abhängigen Namen in der ersten Phase erfolgt, während die Suche nach Namen, die von einem Vorlagenparameter abhängen, in der zweiten Phase erfolgt. Die Bedeutung ist, dass wenn Sie aufrufen sqrt(1), sqrtdiese deklariert werden muss, bevor die Vorlage definiert wird. Wenn Sie jedoch aufrufen sqrt(t), wo tsich eine Instanz eines Typs befindet, der ein Vorlagenparameter ist, sqrtmuss sie erst sichtbar sein, wenn die Vorlage instanziiert wurde. MSVC hat das früher nicht richtig gemacht: immer noch nicht, soweit ich weiß.
Steve Jessop
14
Aus diesem Grund wird es als zweiphasige Suche bezeichnet und nicht nur als zweiphasige Kompilierung oder so. Die erste Phase soll mehr als nur die Syntax überprüfen, aber MS hatte einige Schwierigkeiten, die erste Suchphase zu implementieren, also haben sie alles bei der Instanziierung getan
Steve Jessop
3
Historische Bemerkung: Ich habe einen Compiler verwendet, der eine Zählklammerphase und eine Kompilierungsphase hatte. IOW wurde template <class T> class C { put really anything here & ~ - (but nothing unbalanced and no 8-bit char outside string literal) }akzeptiert, wenn er Cniemals instanziiert wurde! Das war vor mehr als einem Jahrzehnt.
Neugieriger
2
Für Neugierige ist dies ein Auszug aus C ++ - Vorlagen: The Complete Guide .
Legends2k
2
Neben dem Kommentar von @ SteveJessop zu abhängigen Namen ist auch darauf hinzuweisen, dass es sich bei den abhängigen Namen um eine "argumentabhängige Suche" handelt. Dies bedeutet, dass dies ::sqrt(::NS::A)nicht gefunden wird, da die zusätzliche Suche in ::NSund nicht in erfolgt ::. Der letzte Punkt ist, dass der Bereich eines Alias, typedef oder using, nicht durchsucht wird, sondern nur der Bereich des alised-Typs selbst.
Antworten:
Vorlagen werden (mindestens) zweimal kompiliert:
Ohne Instanziierung wird der Vorlagencode selbst auf Syntax überprüft.
ZB: Alle Syntaxfehler wie
;
etc.Zum Zeitpunkt der Instanziierung (wenn der genaue Typ bekannt ist) wird der Vorlagencode erneut überprüft, um sicherzustellen, dass alle Aufrufe für diesen bestimmten Typ gültig sind.
Beispiel: Die Vorlage ruft möglicherweise Funktionen auf, die für diesen bestimmten Typ möglicherweise nicht vorhanden sind.
Dies wird als Zwei-Phasen-Suche bezeichnet.
quelle
sqrt(1)
,sqrt
diese deklariert werden muss, bevor die Vorlage definiert wird. Wenn Sie jedoch aufrufensqrt(t)
, wot
sich eine Instanz eines Typs befindet, der ein Vorlagenparameter ist,sqrt
muss sie erst sichtbar sein, wenn die Vorlage instanziiert wurde. MSVC hat das früher nicht richtig gemacht: immer noch nicht, soweit ich weiß.template <class T> class C { put really anything here & ~ - (but nothing unbalanced and no 8-bit char outside string literal) }
akzeptiert, wenn erC
niemals instanziiert wurde! Das war vor mehr als einem Jahrzehnt.::sqrt(::NS::A)
nicht gefunden wird, da die zusätzliche Suche in::NS
und nicht in erfolgt::
. Der letzte Punkt ist, dass der Bereich eines Alias, typedef oder using, nicht durchsucht wird, sondern nur der Bereich des alised-Typs selbst.