2012-07-07 10 views
10

Dies ist eine nicht zusammenhängende Frage über den Code in this question, in Bezug auf die folgende Template-Funktion.Fehler: ungültige Initialisierung der Referenz vom Typ 'int &' vom Ausdruck des Typs 'const int'

template <class T> 
class Object : public Container { 
public: 
    T& object; 

    Object(const T& obj) : object(obj) {} 
}; 

Dies ist der Code, der den Konstruktor ruft:

template <class T> 
void Array::add_element(const T& element) 
{ 
    vec.push_back(new Object<T>(element)); 
} 

Dieser Code kompiliert gut, aber sobald ich eine Linie in main hinzufügen, dass es nennt:

Array array; 
int i = 3; 
array.add_element(i); 

I Erhalte eine Compiler-Warnung: error: invalid initialization of reference of type 'int&' from expression of type 'const int'.

Worum geht es? Ich habe eine int in. Sollte es nicht automatisch in eine const int& für mich verwandelt werden? Warum beschwert sich der Compiler?

+6

Hinweis ändern: 'T & Objekt;' - auch 'const T & obj = nullptr' keinen Sinn machen , Sie können einen Verweis auf ein 'nullptr' nicht initialisieren. – Xeo

+0

Wie ist das ein Hinweis? Genau so ist 'object' bereits deklariert. Und danke, das werde ich ändern. – anthropomorphic

+2

Es ist ein Hinweis, weil Sie eine nicht-const-Referenz von einer const-Referenz nicht initialisieren können - const-correct 101. – ildjarn

Antwort

12

obj ist eine konstante Referenz. object ist eine nicht-const Referenz.

Sie können eine nichtkonstante Referenz nicht von einer const-Referenz initialisieren, da dies den Zweck einer const-Referenz an erster Stelle zunichte machen würde.

Wenn Sie möchten, dass Ihre Instanz Object die int ändern kann, die an ihren Konstruktor übergeben wird, sollte der Konstruktor eine nicht-konstante Referenz nehmen. Wenn Sie dies nicht tun, sollte das Datenelement eine Konstante sein.

In jedem Fall speichern Sie Probleme für sich selbst, wenn Sie new verwenden, um Objekte zuzuweisen, die Referenzen als Datenmitglieder haben. Es ist Ihr Problem, um sicherzustellen, dass Sie die Object vor i löschen den Gültigkeitsbereich verlassen (oder wie auch immer, sicherzustellen, dass die Object nicht sein Mitglied nicht verwendet object nach i dem Gültigkeitsbereich verläßt.

+0

Ausgezeichnete Antwort. Es funktioniert jetzt. – anthropomorphic

8

Sie sind versuchen, eine zuweisen const Verweis auf eine nicht konstante Referenz. das bedeutet, dass Ihre Objektklasse den Inhalt des Objekts ändern können.

const int myConstNumber = 4; 
Object<int> intObj(myConstNumber); 

intObj.object = 3; // you have indirectly modified the value of myConstNumber 

C++ Sie das tun lassen Sie sich nicht. Sie eine Kopie des Objekts machen oder fügen Sie die const zu Ihrem Attribut

template <class T> 
class Object : public Container { 
public: 
    T object; // valid 

oder

template <class T> 
class Object : public Container { 
public: 
    const T& object; // valid 

in diesem Fall können Sie nicht Objekt

+1

Danke, deine Antwort ist auch gut, aber wer zuerst kommt, mahlt zuerst, sorry =/ – anthropomorphic

+6

Es ist in Ordnung, ich bin hier, um zu helfen, nicht für die Anerkennung. :) – ilmale

Verwandte Themen