I'm debugging a 3D vector code, but I get the following error
/usr/bin/g++ -fdiagnostics-color=always -g /home/fangrui/vectorFEM/vectorFEM/main.cpp -o /home/fangrui/vectorFEM/vectorFEM/main
In file included from /home/fangrui/vectorFEM/vectorFEM/constant.h:6:0,
from /home/fangrui/vectorFEM/vectorFEM/mesh.h:2,
from /home/fangrui/vectorFEM/vectorFEM/edgenedelec.h:2,
from /home/fangrui/vectorFEM/vectorFEM/main.cpp:1:
/home/fangrui/vectorFEM/vectorFEM/cvector3D.h: In function ‘cvector operator*(double, cvector)’:
/home/fangrui/vectorFEM/vectorFEM/cvector3D.h:39:10: error: cannot bind non-const lvalue reference of type ‘cvector&’ to an rvalue of type ‘cvector’
return cvector(x1*x2.x, x1*x2.y, x1*x2.z);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
It's a problem in cvector3D.h
file, but I don't understand this bug and what kind of changes should be made. In addition to the error above, there is also a warning about friend
:
class "cvector" has no suitable copy constructorC/C++(334)
here is the original code for cvector3D.h
# ifndef CVECTOR3D_H
# define CVECTOR3D_H
#include<cmath>
#include<ostream>
#include<iomanip>
using namespace std;
/*A three-dimensional real vector class is defined to facilitate numerical calculations*/
class cvector
{
public:
double x, y, z;
//Construct function
cvector(double _x, double _y, double _z){ x = _x; y = _y; z = _z; }
//Copy the constructor
cvector(cvector &pt){ x = pt.x; y = pt.y; z = pt.z; }
cvector(){ x = 0; y = 0; z = 0; }
~cvector(){};
//Operator overloading
cvector operator +();
cvector operator -(); //The vector is negated
friend ostream &operator<<(ostream &os, const cvector &x1);
cvector operator +(cvector x1);
cvector operator -(cvector x1);
cvector operator *(double x1);
cvector operator /(double x1);
cvector &operator =(cvector x1);
cvector &operator +=(cvector x1);
cvector &operator -=(cvector x1);
cvector &operator *=(double x1);
cvector &operator /=(double x1);
int operator ==(cvector x1);
int operator !=(cvector x1);
friend cvector operator *(double x1, cvector x2) {
return cvector(x1*x2.x, x1*x2.y, x1*x2.z);
}
//Member functions
double dist(cvector x1);
cvector unit();
double norm();
friend cvector cross(cvector x1, cvector x2)
{
return cvector(x1.y*x2.z - x1.z*x2.y, x1.z*x2.x - x1.x*x2.z, x1.x*x2.y - x1.y*x2.x);
}
friend double dot(cvector x1, cvector x2)
{
return (x1.x*x2.x + x1.y*x2.y + x1.z*x2.z);
}
} ;
# endif
The cvector
copy constructor is malformed.
The correct form is cvector(const cvector& cvec)
.
Long Description:
When the friend function
friend cvector operator *(double x1, cvector x2) {
return cvector(x1*x2.x, x1*x2.y, x1*x2.z);
}
is called the construnctor of cvector
is called.
Immediatly after the constructed object is returned by copy, so the copy constructor is called, but the lvalue just created of type cvector&
, that is non-const
cannot be converted to an rvalue of type cvector
.
This because a non-const reference parameter, such as for example an int&,
can only refer to an "lvalue," which is a named variable.
In this case the object created is not a named variable.