[英]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;
}
在上面的示例代碼中,我創建了一個CLS類和一個重載的運算符+。 在+的定義中,我調用了一個函數,該函數的參數包含double*
指針。 在我的真實代碼中,此函數被LAPACK中的函數替換,因此我無法更改它。 因此,當我問這個問題時,我假設我們不會對testfn
進行任何更改,也不必更改必須使用testfn
定義運算符+的事實。 但是我收到以下錯誤消息。 我該如何擺脫它們?
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
后續問題(我無法在90分鍾內發布兩個問題,因此我只在此問題后添加)
#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;
}
我創建了CLS類,並定義了兩個運算符+和*。 我想像使用整數和雙精度數一樣簡單地使用這些運算符。 因此我在主CLS C4=C1*(C1+(C2*C3+C2))*C1;
有一條測試線CLS C4=C1*(C1+(C2*C3+C2))*C1;
。 但是,在編譯此代碼時會出現大量錯誤。 我對運算符重載的規則還不夠熟悉。 我應該如何修改*和+的定義(也許只是參數?),以使CLS C4=C1*(C1+(C2*C3+C2))*C1;
已驗證?
理想情況下,您將testfn
的參數全部更改為const
。 您已經在評論中說了這不是一個選擇。 從這里的定義來看,沒有什么真正的理由不能更改,但我暫時將其忽略。
如果需要+ operator保持const,則可以創建v
和A
深層副本以傳遞給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;
}
如果副本很昂貴,並且您確定testfn
不會修改輸入,則可以const_cast
輸入。
另一種可能性是刪除+運算符上的所有const限定詞:
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;
}
因為testfn
接受的不是const指針,所以您實際上不能保證它不會更改v
或A
內的值。
理想情況下,您應該重新聲明testfn()
以使其只讀參數為const
:
void testfn(const double* v1, const double *v2, double *v3, int n);
但是,如果這不是您的選擇,那么至少可以讓operator+
在使用Av
時簡單地const_cast
消除常數:
CLS CLS::operator+(const CLS &A) const
{
//assuming the two vectors have the same length
vector<double> vtmp(v.size(), 0);
// if the vectors are empty, the begin() iterators
// will match the end() iterators, and dereferencing
// an end() iterator is undefined behavior! So make
// sure the vectors are not empty...
if (!v.empty())
testfn(&*v.begin(), &*const_cast<CLS&>(A).v.begin(), &*vtmp.begin(), (int)v.size());
return CLS(vtmp);
}
順便說一句,使用&*begin()
非常難看,您可以使用std::vector::operator[]
代替:
CLS CLS::operator+(const CLS &A) const
{
//assuming the two vectors have the same length
vector<double> vtmp(v.size(), 0);
// if the vectors are empty, accessing any elements
// is undefined behavior! So make sure the vectors
// are not empty...
if (!v.empty())
testfn(&v[0], &(const_cast<CLS&>(A).v[0]), &vtmp[0], (int)v.size());
return CLS(vtmp);
}
或者,如果您使用的是C ++ 11或更高版本,請改用std::vector::data()
:
CLS CLS::operator+(const CLS &A) const
{
//assuming the two vectors have the same length
vector<double> vtmp(v.size(), 0);
// if the vectors are empty, accessing any elements
// is undefined behavior! So make sure the vectors
// are not empty...
if (!v.empty())
testfn(v.data(), const_cast<CLS&>(A).v.data(), vtmp.data(), (int)v.size());
return CLS(vtmp);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.