Zuweisung an const Referenzen in Templates
-
Hallo zusammen,
bei unten angegebenem Code habe ich folgendes Problem: Und zwar verstehe ich nicht, wieso ich im Konstruktor diese Zuweisung durchführen kann, obwohl m_t const ist. Dies gilt jedoch nur für den Fall, wenn T eine Referenz auf irgendwas ist. Ist T ein Objekt, bekomme ich den erwarteten Compiler-Fehler. Es ist doch quasi genau das gleiche wie in den ersten drei Zeilen von main.Vielen Dank.
peeri
template <typename T> class X{ public: X(T param):m_t(param) { m_t = param; // geht, wenn T Referenz ist. Warum? } const T m_t; }; int main() { int i=1234; const int& ci = i; //ci = i; // geht nicht, weil ci const ist X<int&> x(i); return 0; }
-
es gibt keine const referenzen. das const in der deklaration von m_t wird einfach ignoriert, wenn T ein referenztyp ist.
-
Das const wird nicht ignoriert. Es hat nur keinerlei bedeutung bei referenzen.
nach der initialisierung verhält sich eine Referenz genau wie das Objekt, das es darstellt. der op= ist also nicht der der Referenz, sonder der vom Objekt.m_t = param;Hier veränderst du also nurnoch das objekt hinter m_t und nicht m_t selber. Da sich das const aber nur auf die Referenz bezieht und nicht auf das Objekt, ist dies legal.
In deinem Beispiel in der main ist die sache etwas anders. Ich mach das mal mit Klammern deutlich:
//du denkst, es wäre so: const (int&) ci = i; //der compiler interpretiert das aber so: (const int)& ci = i; //den ersten Fall würdest du so erreichen int& const ci = i;Hier versuchst du also, dem constanten Objekt hinter der referenz etwas zuzuweisen, was natürlich nicht gehen kann. Auch wenn constante referenzen natürlich keinen Sinn machen, ist das wissen darüber schon recht wichtig, da sich zeiger exakt genauso verhalten. Einen zeiger macht man also konstant, indem man das const hinter das "*" setzt. Das Objekt hinter einem zeiger wird konstant, wenn das const am Anfang ist.
-
Vielen Dank für die ausführliche Antwort. Jetzt wird mir schon einiges klarer.
Gruß
peeri
-
otze schrieb:
Das const wird nicht ignoriert.
int& const ci = i;ill-formed nach 8.3.2/1