Zweiphasensuche - Erklärung erforderlich

74

Was bedeutet es, dass der Compiler eine zweiphasige Suche verwendet, um die Vorlagenklasse zu kompilieren?

smallB
quelle
1
@Nawaz Ich habe nur von zweiphasiger Suche gehört. Fehlt mir etwas?
smallB
2
Ein kurzer und nützlicher Artikel zu diesem Thema kann unter blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html gefunden werden
Nikola Smiljanić

Antworten:

67

Vorlagen werden (mindestens) zweimal kompiliert:

  1. Ohne Instanziierung wird der Vorlagencode selbst auf Syntax überprüft.
    ZB: Alle Syntaxfehler wie ;etc.

  2. 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.

Alok Speichern
quelle
49
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.
Richard Corden