Home > Back-end >  initial value of reference to non-const must be an lvalue, Passing an object type by reference error
initial value of reference to non-const must be an lvalue, Passing an object type by reference error

Time:03-23

I get the following error when I try to pass a Point object by reference by keeping Point x and y member variables as private, which is why I get x and y by function GetX() and GetY() how do I resolve the error and get it to work as I expect it to.

error log :

CppReview.cpp: In function 'int main()':
CppReview.cpp:92:30: error: cannot bind non-const lvalue reference of type 'Point&' to an rvalue of type 'Point'
   92 |     v.OffSetVector(v.GetStart(),1,3);
      |                    ~~~~~~~~~~^~
CppReview.cpp:79:34: note:   initializing argument 1 of 'void Vector::OffSetVector(Point&, int, int)'
   79 | void Vector::OffSetVector(Point& p,int xoffset,int yoffset){

code :


class Point{
    private:
        int x,y;
    public:
        Point(){
            x = y = 0;
        }
        Point(int x,int y){
            this->x = x;
            this->y = y;
        }
        Point(float x,float y){
            this->x = x;
            this->y = y;
        }
        void SetX(int x){
            this->x = x;
        }
        
        void SetY(int y){
            this->y = y;
        }
        void Display(){
            cout<<"("<<this->x<<','<<this->y<<")\n";
        }
        void move(int i=0,int j=0){
            this->x =i;
            this->y =j;
        }

        int& GetX(){
            return (this->x);
        }

        int& GetY(){
            return this->y;
        }
};

class Vector{
    Point start,end;
    public:
    Vector(){
        this->start = Point(0,0);
        this->end = Point(1,1);
    }
    Vector(int sx,int sy,int ex,int ey){
        this->start = Point(sx,sy);
        this->end = Point(ex,ey);
    }
    float ComputeDistance(Point,Point);
    Point GetStart();
    Point GetEnd();
    void OffSetVector(Point&,int,int);
    void Show();
};

float Vector::ComputeDistance(Point p1,Point p2){
    int p1x = p1.GetX();
    int p1y = p1.GetY();
    int p2x = p2.GetX();
    int p2y = p2.GetY();
    float dist = sqrt((p1x-p2x)*(p1x-p2x) (p1y-p2y)*(p1y-p2y));
    return dist;
}

Point Vector::GetStart(){
    return this->start;
}

Point Vector::GetEnd(){
    return this->end;
}

void Vector::OffSetVector(Point& p,int xoffset,int yoffset){
    p.GetX() =xoffset;
    p.GetY() =yoffset;
}


void Vector::Show(){
    cout<<this->GetStart().GetX()<<','<<this->GetStart().GetY()<<" : "<<this->GetEnd().GetX()<<','<<this->GetEnd().GetY()<<"\n";
}



int main(){
    Vector v(1,1,3,3);
    v.Show();
    v.OffSetVector(v.GetStart(),1,3);
    return 0;
}

CodePudding user response:

The function GetStart returns a temporary object of the type Point

Point GetStart();

while teh function OffsetVector excepts a non-constant reference to an object.

void OffSetVector(Point&,int,int);

You may not bind a temporary object with a non-cinstant lvalue reference.

Change the declaration of the function GetStart like

Point & GetStart();

Also at least the function GetEnd should be changed like

Point & GetEnd();

You could overload the functions for constant and non-constant objects

Point & GetSgtart();
cosnt Point & GetStart() const;
Point & GetEnd();
const Point & GetEnd() const;

CodePudding user response:

The problem is that the expression v.GetStart() is an rvalue of type Point and thus it cannot be bind to a non-const lvalue reference such as Point&.

To solve this you need to change the first parameter named p of the member function OffSetVector as shown below:

class Vector{
//--------------------vvvvv------------------>const added here
    void OffSetVector(const Point&,int,int);
    
};

//------------------------vvvvv------------------------------------>const added here
void Vector::OffSetVector(const Point& p,int xoffset,int yoffset){
    
//----------vv------------>  = won't work here because of the added const
    p.GetX() =xoffset; 
//----------vv------------>  = won't work here because of the added const
    p.GetY() =yoffset;
}

But note that the above won't work because of the added const.

Solution

So to solve the problem you should change the return type of GetStart to Point& as shown below:

class Vector{
//-------v----------------->return by reference
    Point& GetStart();
    
};
//---v--------------------->return by reference
Point& Vector::GetStart(){
    return this->start;
}

Working Demo

Similarly, you should change the return type of GetEnd as well to be Point& instead of Point. Moreover, there is also an option for overloading GetStart and GetEnd for const and non-const objects.

  • Related