Resorter Resorter - 1 month ago 12
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

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.

Comments