Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: invalid initialization of reference of type 'int&' from expression of type 'const int'

This is an unrelated question about the code in this question, regarding the following template function.

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

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

This is the code that calls the constructor:

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

This code compiles fine, but as soon as I add a line in main that calls it:

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

I get a compiler warning: error: invalid initialization of reference of type 'int&' from expression of type 'const int'.

What is that about? I passed an int in. Shouldn't it automatically be turned into a const int& for me? Why is the compiler complaining?

like image 459
Michael Dorst Avatar asked Jul 07 '12 00:07

Michael Dorst


2 Answers

obj is a const reference. object is a non-const reference.

You can't initialize a non-const reference from a const reference, because doing so would defeat the purpose of having a const reference in the first place.

If you want your instance of Object to be able to modify the int that's passed to its constructor, then the constructor should take a non-const reference. If you don't, then the data member should be a const reference.

In any case, you are storing up trouble for yourself if you use new to allocate objects that have references as data members. It's your problem to ensure that you delete the Object before i goes out of scope (or anyway, ensure that the Object doesn't use its member object after i goes out of scope.

like image 195
Steve Jessop Avatar answered Sep 21 '22 16:09

Steve Jessop


You are trying to assign a const reference to a non const reference. This means that your Object class can modify the content of object.

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

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

C++ doesn't let you do that. You can make a copy of the object or add the const to your attribute.

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

or

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

in this case you won't be able to modify object

like image 41
ilmale Avatar answered Sep 22 '22 16:09

ilmale