views:

46

answers:

3

Here is the problem. I wrote this function to return a reference to the i element of a member vector, so this element could be edited. Here is the code:

Letter& Literal::get (int i) const {

   return lit_m.at (i); //Vector of Letter objects
}

But g++ won't let me assign that element to a non-const reference:

g++ -o literal.o -c literal.cpp
literal.cpp: In member function ‘Letter& Literal::get(int) const’:
literal.cpp:34: error: invalid initialization of reference of type ‘Letter&’ from expression of type ‘const Letter’

How could it be solved? My idea is to build up a function like the at() function of vectors, so it would be const as it doesn't edit the object itself, but it should let me edit the returned object...Is it possible?

SOLVED: I just had to overload the function :), so declare a const and a non-const version. I was afraid that const and non-const overloading wasn't permitted, but I saw that that const changes the argument list, making it possible.

+4  A: 

The problem is this member function :

Letter& get (int i) const

you declared it const, and because of that,

const T& at() const

member function of the vector class is called, returning you const reference to the i-th item, therefore you can not modify it.

If you really need to modify that element, do not declare your get() function as const, and return reference to the element like you are doing now.

by the way, you declared the function const, and you are returning non-const reference.

VJo
+1, good answer
Green Code
A: 

That isn't const-correct. You are changing a member variable of the class (the vector), so g++ is seeing this as an error. When you declare a method as const and return a member variable the expectation is that the value returned is used for inspection not mutation.

GWW
+2  A: 

There's a very good reason why this produces an error. The object of your class should be constant to preserve its state. When you return a reference to one of its internal variables, you're allowing someone to change the value of that internal variable, thus changing the state of the object, making it no longer a constant function.

Something that might be possible is if the Literal class contained a vector of pointers to Letter objects instead of letter objects, you can successfully return a ponter to one of those Letter objects without issues.

Letter* Literal::get (int i) const {
   return lit_m.at (i); //Vector of pointers to Letter objects  
} 

Probably an article everyone dealing with pointers should read (or any language allowing the const keyword, but 10x more so if pointers are involved) can be found here. Honestly, I probably should look over it again myself.

Shynthriir
Actually you have given him the solution. As long as the pointer will never be NULL you can dereference it.
CashCow
I wasn't sure if it was valid because I was thinking if it was a const method, it would probably actually return either `Letter* const` or `const Letter*` and in the second case, he would be in the same boat as before.
Shynthriir