Resorter Resorter - 11 months ago 44
C++ Question

When overload an operator in C++, how to get around with invalid conversion from 'const double*' to 'double*'

#include <iostream>
#include <vector>
using namespace std;


void testfn(double* v1, double *v2, double *v3, int n);//I must use this function

class CLS{
private:
vector<double> v;
public:
CLS(vector<double> vin);
CLS operator+(const CLS & A)const;
};

CLS::CLS(vector<double> vin)
{
v=vin;
}

CLS CLS::operator+(const CLS &A)const{
//assuming the two vectors have the same length
vector<double> vtmp(v.size(),0);
testfn(&*v.begin(),&*A.v.begin(),&*vtmp.begin(),(int)v.size());
CLS C(vtmp);
return C;
}

void testfn(double* v1, double *v2, double *v3, int n)
{
for (int i=0;i<n;i++)
{
*v3=*v1+*v2;
++v1;
++v2;
++v3;
}
}

int main(){
vector<double> v1(100,1.0), v2(100,2.0);
CLS C1(v1),C2(v2);
CLS C3=C1+C2;
return 0;
}


In the above sample code, I create a class CLS and an overloaded operator +. In the definition of +, I call a function whose parameters contain
double*
pointers. In my real code this function is replaced by a function in LAPACK so I can not change it. Therefore when I ask this question, I assume we do not change anything about
testfn
and the fact that we must use
testfn
to define operator +. But I got the following error messages. How can I get rid of them?

test1.cpp: In member function 'CLS CLS::operator+(const CLS&) const':
test1.cpp:25:66: error: invalid conversion from 'const double*' to 'double*' [-fpermissive]
testfn(&*v.begin(),&*A.v.begin(),&*vtmp.begin(),(int)v.size());
^
test1.cpp:6:6: note: initializing argument 1 of 'void testfn(double*, double*, double*, int)'
void testfn(double* v1, double *v2, double *v3, int n);
^
test1.cpp:25:66: error: invalid conversion from 'const double*' to 'double*' [-fpermissive]
testfn(&*v.begin(),&*A.v.begin(),&*vtmp.begin(),(int)v.size());
^
test1.cpp:6:6: note: initializing argument 2 of 'void testfn(double*, double*, double*, int)'
void testfn(double* v1, double *v2, double *v3, int n);
^
make: *** [test1.o] Error 1


A follow up question (I can not post two questions in 90 minutes so I just add it behind this one)

#include <iostream>
#include <vector>
using namespace std;

void testfn(double* v1, double *v2, double *v3, int n);//I must use this function

class CLS{
private:
vector<double> v;
public:
CLS(vector<double> vin);
CLS operator+(CLS & A);
CLS operator*(CLS & A);
};

CLS::CLS(vector<double> vin)
{
v=vin;
}

CLS CLS::operator*(CLS &A){
//assuming the two vectors have the same length
vector<double> vtmp(v.size(),0);
testfn(&*A.v.begin(),&*v.begin(),&*vtmp.begin(),(int)A.v.size());
CLS C(vtmp);
return C;
}

CLS CLS::operator+(CLS &A){
//assuming the two vectors have the same length
vector<double> vtmp(v.size(),0);
testfn(&*A.v.begin(),&*v.begin(),&*vtmp.begin(),(int)A.v.size());
CLS C(vtmp);
return C;
}

void testfn(double* v1, double *v2, double *v3, int n)
{
for (int i=0;i<n;i++)
{
*v3=*v1+*v2;
++v1;
++v2;
++v3;
}
}

int main(){
vector<double> v1(100,1.0), v2(100,2.0), v3(100,0.0);
CLS C1(v1),C2(v2),C3(v3);
CLS C4=C1*(C1+(C2*C3+C2))*C1;
return 0;
}


I create class CLS and defined two operators + and *. I want to use these operators as simply as how we use + and * for integers and doubles. Therefore I have a test line in the main
CLS C4=C1*(C1+(C2*C3+C2))*C1;
. However I get tons of errors when compiling this code. I am not familiar enough with the rules of operator overloading. How should I modify the definition (maybe just parameters?) of * and + so that
CLS C4=C1*(C1+(C2*C3+C2))*C1;
is valid?

Answer Source

Ideally, you would change the parameters of testfn to all be const. You have said in the comments that isn't an option. From your definitions here there isn't really a reason they can't be changed, but I'll ignore that for now.

If you need the +operator to remain const, you could create deep copies of v and A to pass in to test_fn.

CLS CLS::operator+(const CLS & A) const
{
    //assuming the two vectors have the same length
    vector<double> vtmp(v.size(), 0);
    vector<double> v1 = v;
    vector<double> v2 = A.v;
    testfn(&*v1.begin(), &*v2.begin(), &*vtmp.begin(), (int)v.size());
    CLS C(vtmp);

    return C;
}

Another possibility would be to remove all the const qualifiers on the +operator:

CLS CLS::operator+(CLS & A)
{
    //assuming the two vectors have the same length
    vector<double> vtmp(v.size(), 0);
    testfn(&*v.begin(), &*A.v.begin(), &*vtmp.begin(), (int)v.size());
    CLS C(vtmp);
    return C;
}

because testfn takes pointers that aren't const, you don't really have any guarantee that it isn't changing the values inside of v or A.