invalid initialization of non-const reference - c++

Alright, I'm trying to figure out this error and have, so far, had absolutely no luck. I'm doing this for homework, which is why I'm not using included classes.
Here's the relevant code:
//Will return an array where each element is the sum of the respective sums in the added arrays
Vec& Vec::operator+(Vec& v2) const{
Vec ret();
if(mySize>0){
Vec ret(mySize);
for(unsigned i = 0;i<mySize;i++){
ret[i]=v2[i]+myArray[i];
}
}
else{
}
return ret;
}
And from the .h file...:
Vec& operator+ (Vec& v2) const;
This throws the error: "invalid initialization of non-const reference of type ‘Vec&’ from an rvalue of type ‘Vec (*)()’"
I'm completely new to C++, so any help would be appreciated.

Vec ret();
Is taken to be a forward declaration of a function which takes no arguments and returns a Vec. See: the most vexing parse.
Next, you're returning a reference to a local variable, which is bad. ret goes out of scope as soon as the function returns.

The actual error is that you are declaring a function inside of your operator, instead of declaring a Vec object.
Vec ret();
You can fix that by omitting the ():
Vec ret;
Besides that, you have a fundamental design error in that you are attempting to return a reference to a variable which is local to the scope of your operator, resulting in a dangling reference. The usual way to express an addition operator is to have it return a new object, and is typically implemented as a non-member function with a signature such as
Vec operator+(const Vec& lhs, const Vec& rhs);
This can be implemented in terms of an increment member operator
Vec& operator+=(const Vec& rhs);
This one can return a reference to this hence no dangling reference. An example implementation od operator+ would then be
Vec operator+(Vec lhs, const Vec& rhs)
{
return lhs += rhs;
}

As others have stated your initial declaration of ret which you think is default constructing a Vec is actually forward delcaring a function which takes no arguments and returns a Vec. AKA the most vexing parse.
Also the variable shadowing of 'ret' inside the if statement means that you are not modifying the variable that you are expecting to return. It's likely that you want something more like this:
Vec Vec::operator+(const Vec& v2) const{
Vec ret(mySize);
if(mySize>0){
for(unsigned i = 0;i<mySize;i++){
ret[i]=v2[i]+myArray[i];
}
}
else{
}
return ret;
}

Related

Operator Overloading with Constant Iterators

I have a constant iterator class which contains the following methods for overloading several operator functions
self_reference operator=( const SDAL_Const_Iter& src ) {
index = src.index;
return *this;
}
self_reference operator++() {
index = index + 1;
return *this;
}
self_type operator++(int) {
SDAL_Const_Iter results = *this;
++index;
return results;
}
The index variable is of type const int.
My compiler is complaining that I am attempting to modify a constant object (More specifically, "Error C2166: l-value specifies constant object"), which I am aware of; however, I see no other way of overloading these functions. Can someone please elaborate on how to go about writing these overloads without causing compiler issues?
I believe the problem is in const int as index variable.
A constant iterator should not allow non-const access to the container's data. The iterator itself, though, is changeable (it has to be able to iterate). Changing index to int should fix the problem.

How can I overload operator[] to allow for `object[a] = b`?

It's possible to overload operator[] to take one argument, in the brackets. However how can I overload this operator to allow the user to type object[a] = b?
You return a reference to your item, something like:
A &operator[](int pos) { return list[pos]; }
So when you say object[a]=b; it's actually translated to:
A &tmp=object[a];
tmp=b;
Or in more clear terms:
A *tmp=object[a]; // more or less a pointer
*tmp=b; // you replace the value inside the pointer
The general declaration of the operator (it shall be a class member function) is the following
ObjectElementType & operator []( size_t );
Subscript operators often comes in pair :-
T const& operator[] (size_t ) const;
T& operator[] (size_t ); // This enables object[a] = b on non-const object

Const correctness and operator *

I defined a class like this:
Quaternion& conjugate(); //negates the vector component of the quaternion
Quaternion conjugate() const; //same but in without modifying the class...
Quaternion& operator = (Quaternion const& Qrhs);
Quaternion& operator *= (Quaternion const& Q);
Quaternion operator * (Quaternion const& Qrhs) const;
now I use this functions like this:
PRINTVAR(*this); //this is the first time printed (a little macro to print line and file)
Quaternion vQ(0.,vn), resQ;
resQ = vQ*(this->conjugate()); //this is the method I want to discuss...
PRINTVAR(*this); //this is the second time
resQ = *this * resQ;
and this is the output
*this: (0:0:0:0) at line: 128 in file: Quaternions.cpp
*this: (-0:-0:-0:0) at line: 131 in file: Quaternions.cpp
I thought that by calling the operator * in the line resQ = vQ*(this should be called as const)...
why if I print *this again is changed?
here is the definition of the conjugate function:
Quaternion& Quaternion::conjugate(){
/* Given: Nothing
* Task: Invert sign of the vector
* Return: the class which will be modified
*/
V3 vec;
vec = -(this->getVector());
x() = vec[0];
y() = vec[1];
z() = vec[2];
return *this;
}
Quaternion Quaternion::conjugate() const{
Quaternion result(*this);
result.conjugate();
return result;
}
If the code you showed is in a non-const method, than the this pointer is non-const, and the non-const conjugate method is of course a better match than the const one. Return types aren't considered in overload decisions. If you want to insist that the const version is used, you can add constness: resQ = vQ*(static_cast<const Quaternion*>(this)->conjugate());
Probably the method in which you are using this is non-const.
The type of this a member function of a type A, is A * const. For const member function it is const A * const.
Therefore, your code will work as you expect it to do if you enter your code into const method.
If you want to force calling const overload of function you will need to do a const-cast:
const_cast<const Quaternion * const>(this)->conjugate();
*this is not const (although it is used in a const method), and the c++ FAQ Lite states regarding const overloading (in the FAQ's case on a subscript operator);
When you apply the subscript operator to a MyFredList object that is
non-const, the compiler will call the non-const subscript operator.
Translated, since *this is non-const, the non-const method will be called.

why sometime a function return a const, or const reference

First, why return const?
say I have
friend const MyVec operator-(const MyVec& left, const MyVec& right)
so is returning const makes me cannot do:
mva - mvb = mvc;
Second, why return const reference?
if there is:
friend const MyVec& operator++(MyVec& v)
with const I cannot: (++mva) = mvc
if it is
MyVec& operator++(MyVec& v)
I can:++(++mva) // with increment twice.
am I understanding right?
There is not any good reason to return a const object. However, there are many good reasons to return pointers or references to const objects.
The program might have an object that is very expensive to copy, so it returns a reference. However, the object should not be changed through that reference. For example, it might be part of a sorted data structure and if its values were modified it would no longer be sorted correctly. So the const keeps it from being modified accidentally.
Arithmetic operator functions should not return const objects, because of exactly the problems in your question.
Dereferencing an iterator should return a const reference. That is if it is operating on a collection of const objects or possibly on a const collection. This is why class functions sometimes have two copies of a function with the second copy using a const on the function itself, like this:
T& operator[](size_t index);
const T& operator[](size_t index) const;
The first function would be used on non-const objects and the second function would be used for const objects.
Yes your understanding is correct. To avoid accidental assignments, one can return an object by const or const reference.
With operator -, you return an object by value. To avoid it getting edited accidently, one can return by const value, because anyways the object will be mostly a temporary.
For operator ++, conventionally it returns reference, however to avoid situations as (++ x) = y; you can return it by const reference.

C++: "const" in front of a class method

Taking for example this method declaration:
const Vector Vector::operator - ( const Vector& other ) const;
I know that the second const makes the Vector passed as an argument immutable, and that the last const declares that the method does not change the current instance of the Vector class....
But what exactly does the first const mean or lead to?
It is an outdated security measure to prevent nonsense code like a - b = c to compile.
(I say "outdated" because it prevents move semantics which only works with non-const rvalues.)
The first const means that this operator will return a constant Vector object.
It means the return value is a const Vector.
It has more meaning in cases such as this: const int& Vector::get(int index) const;