2016-07-26 9 views
-2

Ich frage mich, wie Template Member-Funktionen arbeiten. Wenn die Template-Member-Funktion instanziiert wird, wird die gesamte Klasse neu definiert? Meine Verwirrung kommt von der Tatsache, dass Template-Klassen (wenn ich recht habe) keine Klassen im eigentlichen Sinne sind. wenn er instanziiert wird, erstellt der Compiler die Definition für eine vollständig neue Klasse. Das Gleiche gilt für Vorlagenfunktionen. Allerdings scheinen Klassen mit einer Template-Funktion echte Klassen zu sein, daher bin ich mir nicht sicher, wie sie funktionieren könnten. Daher frage ich mich, ob nach der Instanziierung einer Template-Member-Funktion was mit der Klassendefinition passiert? Wenn ich eine Klasse mit einer Template-Member-Funktion an eine Template-Klasse übergebe, kann ich dann die Template-Member-Funktion verwenden? Könnte das ein Problem verursachen? Ich habe es einmal ausprobiert, aber es wurde ein Fehler gemeldet, dass mehrere Funktionen mehr als einmal definiert wurden, obwohl ich mir nicht sicher bin, ob das der Grund war oder ob es einen anderen Grund für meinen Fehler geben könnte. Gibt es weitere Einschränkungen bei der Verwendung von statischen Vorlagenelementfunktionen?Wie funktionieren Template-Member-Funktionen in C++?

+0

Eine Spezialisierung einer Vorlage, ob Klassenvorlage oder Funktionsvorlage, wird instanziiert, wenn sie zum ersten Mal in einer Übersetzungseinheit verwendet wird. Klassen können Mitgliedervorlagen (sowohl Klassen- als auch Funktionsvorlagen) und Klassenvorlagen haben. Darüber hinaus sind Elementfunktionen von Klassenvorlagen selbst implizit Funktionsvorlagen. –

+0

Beachten Sie, dass eine Vorlage niemals instanziiert wird. Nur * Spezialisierungen * einer Vorlage können instanziiert werden. –

+0

Sehr gut, danke. –

Antwort

2

Die Klassendefinition bleibt so wie sie ist; Die gesamte Template-Funktion erzeugt eine Familie von Member-Funktionen für diese Klasse. Als Beispiel:

class A { 
    public: 
     template<typename T> foo (T &t); 
} 

Ist das nicht konzeptionell verschieden von Ihnen zu schreiben:

class A { 
    public: 
     foo (bool &t); 
     foo (int &t); 
     foo (double &t); 
} 

... einfach bequemer. Und im letzten Beispiel würden Sie nicht erwarten, dass für jede Funktion eine neue Klasse erstellt würde, oder?

Vielleicht kommt die Verwirrung von der Vorstellung, dass Funktionen irgendwie Teil des Speicherlayouts einer Klasse sind; dass jede Funktion selbst in der Klasse enthalten ist und irgendwo im Speicher instanziiert wird, wenn ein Objekt der Klasse erstellt wird. Dieser Begriff ist falsch. Funktionen (templated, global, member, lambda oder andere) werden niemals im Handumdrehen erstellt oder im Speicher kopiert. Sie sind ein statischer und unveränderlicher Teil des ausführbaren Bildes. Das Speicherlayout der Klasse wird durch das Vorhandensein eines zusätzlichen Satzes von Funktionen nicht geändert, selbst wenn diese zufällig von einem Vorlagenelement erzeugt werden.

+0

Im Beispiel scheint es einige starke Typisierungskonzepte zu geben. Die Verwendung von Templates mit Typen führt zu neuen Typen, wobei Ihr 'foo'' A * x = new A (true); 'oder' A * y = new A (123); 'haben kann, wobei' x' und 'y' enden Da derselbe Typ – infixed

+0

@infixed 'foo' kein Konstruktor ist, wird Ihr Beispielcode nicht angewendet. Die Frage bezieht sich speziell auf Nicht-Template-Klassen mit einer Template-Member-Funktion. Es werden keine neuen Typen erstellt. –

0

Die Template-Klassendefinition wird instanziiert, wenn Sie eine Klasse instanziieren. Jede Mitgliedsfunktion wird bei ihrer Verwendung instanziiert. Dadurch können Sie Memberfunktionen haben, die nicht funktionieren würden, wenn sie aufgerufen werden, wenn die Klasse mit einigen Typen und nicht mit anderen Typen instanziiert wird. Sie müssen jedoch sicherstellen, dass die Signatur der Funktion entweder syntaktisch lebensfähig ist oder mit SFINAE fehlschlägt. Es wird in der ersten Phase des Parsens nachgeschlagen. Wenn die Funktion selbst keine Vorlage ist, wird der Body auf Namens-Lookup geprüft ... so müssen abhängige Namen als solche über typename gekennzeichnet werden.

+0

Ich glaube nicht, dass das recht ist.Es gibt keine "Template-Klassendefinition". Es gibt eine * Klassenvorlagendefinition *, die jedoch niemals instanziiert wird. Nur * Spezialisierungen * der Vorlage werden instanziiert. Darüber hinaus wird eine Spezialisierung nicht bei jeder Verwendung instanziiert, sondern nur beim ersten Mal (innerhalb jeder Übersetzungseinheit). –

Verwandte Themen