Error: неверная инициализация ссылки типа 'int &' из выражения типа 'const int'
Это несвязанный вопрос о коде в этом вопросе относительно следующей функции шаблона.
template <class T>
class Object : public Container {
public:
T& object;
Object(const T& obj) : object(obj) {}
};
Это код, вызывающий конструктор:
template <class T>
void Array::add_element(const T& element)
{
vec.push_back(new Object<T>(element));
}
Этот код компилируется отлично, но как только я добавляю строку в main
, которая ее вызывает:
Array array;
int i = 3;
array.add_element(i);
Я получаю предупреждение о компиляторе: error: invalid initialization of reference of type 'int&' from expression of type 'const int'
.
Что это значит? Я передал int
дюйм. Разве он не должен автоматически превращаться в const int&
для меня? Почему компилятор жалуется?
Ответы
Ответ 1
obj
является ссылкой на константу. object
- это неконстантная ссылка.
Вы не можете инициализировать ссылку, отличную от const, из ссылки const, поскольку это может привести к тому, что в первую очередь будет иметь ссылку на const.
Если вы хотите, чтобы ваш экземпляр object
мог модифицировать int
, переданный его конструктору, конструктор должен взять неконстантную ссылку. Если вы этого не сделаете, то элемент данных должен быть константной ссылкой.
В любом случае вы сами сохраняете проблемы, если используете new
для выделения объектов, имеющих ссылки в качестве элементов данных. Ваша проблема в том, что вы удалите object
до того, как i
выходит за рамки (или, во всяком случае, убедитесь, что object
не использует свой член object
после i
выходит за пределы области видимости.
Ответ 2
Вы пытаетесь присвоить константную ссылку неконстантной ссылке. Это означает, что ваш класс Object может изменять содержимое объекта.
const int myConstNumber = 4;
Object<int> intObj(myConstNumber);
intObj.object = 3; // you have indirectly modified the value of myConstNumber
C++ не позволяет вам сделать это. Вы можете сделать копию объекта или добавить const к вашему атрибуту.
template <class T>
class Object : public Container {
public:
T object; // valid
или же
template <class T>
class Object : public Container {
public:
const T& object; // valid
в этом случае вы не сможете изменить объект