Il s'agit d'une question sans rapport avec le code dans cette question , concernant la fonction de modèle suivante.
template <class T>
class Object : public Container {
public:
T& object;
Object(const T& obj) : object(obj) {}
};
C'est le code qui appelle le constructeur:
template <class T>
void Array::add_element(const T& element)
{
vec.Push_back(new Object<T>(element));
}
Ce code se compile très bien, mais dès que j'ajoute une ligne dans main
qui l'appelle:
Array array;
int i = 3;
array.add_element(i);
Je reçois un avertissement du compilateur: error: invalid initialization of reference of type 'int&' from expression of type 'const int'
.
De quoi s'agit-il? J'ai passé un int
po. Ne devrait-il pas être automatiquement transformé en const int&
pour moi? Pourquoi le compilateur se plaint-il?
obj
est une référence const. object
est une référence non constante.
Vous ne pouvez pas initialiser une référence non const à partir d'une référence const, car cela irait à l'encontre du but d'avoir une référence const en premier lieu.
Si vous voulez que votre instance de Object
puisse modifier le int
qui est passé à son constructeur, alors le constructeur doit prendre une référence non const. Si vous ne le faites pas, le membre de données doit être une référence const.
Dans tous les cas, vous enregistrez des problèmes pour vous-même si vous utilisez new
pour allouer des objets qui ont des références en tant que membres de données. C'est votre problème pour vous assurer que vous supprimez le Object
avant que i
ne soit hors de portée (ou de toute façon, assurez-vous que le Object
n'utilise pas son membre object
après i
est hors de portée.
Vous essayez d'affecter une référence const à une référence non const. Cela signifie que votre classe Object peut modifier le contenu de l'objet.
const int myConstNumber = 4;
Object<int> intObj(myConstNumber);
intObj.object = 3; // you have indirectly modified the value of myConstNumber
C++ ne vous laisse pas faire ça. Vous pouvez faire une copie de l'objet ou ajouter la constante à votre attribut.
template <class T>
class Object : public Container {
public:
T object; // valid
ou
template <class T>
class Object : public Container {
public:
const T& object; // valid
dans ce cas, vous ne pourrez pas modifier l'objet