Problem mit Templates - oder Compiler
-
Hi,
ich versuche gerade einen AVL-Baum zu schreiben. Da ich bisher noch nie mit templates gearbeitet habe, war dies für mich die erste Möglichkeit diese Art von Programmierung kennenzulernen.template <class Temp, class Comp> typename AVLBaum<Temp, Comp>::AVLNode* AVLBaum<Temp, Comp>::AVL_Maximumsuche(const AVLNode* const Knoten) { const int Wert = 4; Wert = 5; if(!Knoten) return NULL; while(Knoten->rc) Knoten = Knoten->rc; return Knoten; }Normalerweise dürfte doch so ein Code wegen der Verletzung der Konstantheit niemals kompiliert werden. Allerdings nimmt mein Compiler das klaglos an. Woran liegt das? - Liegt das an den Templates, dass das erst geprüft wird, wenn sie direkt für einen Datentyp initialisiert werden? Ich hab schon eine Instanz des AVL-Baums für Integer Variablen erstellt (ohne Methoden aufzurufen), der Compiler meckert aber immer noch nicht.
Was muss ich ändern, damit der Compiler endlich wieder diese Fehler erkennt? (Benutze VC++ 2008 - hab auch schon ein neues Testprojekt ohne Templates erstellt, in dem hat der Compiler endlich gemeckert)
Vielen Dank für eine Antwort
Andreas
-
"Was muss ich ändern, damit der Compiler endlich wieder diese Fehler erkennt?"
Template Klassen werden erst bei der Nutzung kompiliert,
Das gleiche gilt auch für Template Funktionen - die werden nur auf synthax geprüft, aber richtig geparst werden sie nur, wenn sie gebraucht werden - also ruf mal diese fkt aufbb
-
hi, vielen Dank habs ausprobiert- und noch ne Menge mehr Fehler in den anderen Methoden gefunden.
Gibts denn ne Möglichkeit den Compiler so einzustellen, dass er so offensichtliche Dinge sofort erkennt?
-
Andreas_L schrieb:
Gibts denn ne Möglichkeit den Compiler so einzustellen, dass er so offensichtliche Dinge sofort erkennt?
So offensichtlich ist das gar nicht:
Was wäre, falls AVLNode für irgendeine Spezialisierung bereits const-qualifiziert ist?Bei expliziter Instantiierung eines Klassentemplates werden alle Member ebenfalls instantiiert. Das kann man zum bequemen Testen mit benutzen (geht nat. nicht, wenn das Template Member enthält, die für bestimmte Spezialiserungen gar nicht existieren sollen).
Edit: hab die Zuweisung an Knoten übersehen, das wäre tatsächlich sofort diagnostizierbar.
-
const AVLNode* const KnotenDas zweite
constsorgt nur dafür, dass der kopierte Zeiger nicht verändert wird, ist also nicht allzu sinnvoll. Selbst mit der ZuweisungKnoten = Knoten->rc;wird der originale Zeiger nicht verändert, dazu müsstest du diesen als Referenz übergeben.
-
"Edit: hab die Zuweisung an Knoten übersehen, das wäre tatsächlich sofort diagnostizierbar."
was?
du hältst den teil:if(!Knoten) return NULL; while(Knoten->rc) Knoten = Knoten->rc; return Knoten;für leichter diagnostizierbar als
const int Wert = 4; Wert = 5;?
hab ich das falsch verstanden oder wieso sollte das so sein?
bb
-
unskilled schrieb:
hab ich das falsch verstanden
ja. Diesen Teil des Codes habe ich komplett überlesen, weil er uninteressant ist. Das Erste, was mir aufgefallen war, ist die Diskrepanz zwischen Rückgabetyp und Argument. So ist das eben mit der selektiven Wahrnehmung

-
camper, so ging es mir auch. Den unwichtigen Teil habe ich genauso überlesen...
Daran sieht man nun aber auch, auf welcher Ebene die Templates geparst werden, d.h. die constness wird erst semantisch überprüft (nicht schon bei der reinen syntaktischen Überprüfung).
P.S: Evtl. vllt. wegen eines möglichen const_cast?
-
Welcher Compiler? Denn wenn ich mich nicht irre, müssten solche Schnitzer schon beim Parsen des Templates und nicht erst beim Instantiieren gefunden werden. Manche COmpiler nehmens aber mit den zwei Phasen nicht so genau.
-
template<typename T> void foo(T x) { const int y = 3; ++y; } int main() { //foo(123); }msvc9 kompiliert das anstandslos - so gar, als ich ausversehen statt y x geschrieben hatte...
bb