簡體   English   中英

在C ++中重載運算符時,如何解決從'const double *'到'double *'的無效轉換

[英]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,則可以創建vA深層副本以傳遞給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指針,所以您實際上不能保證它不會更改vA內的值。

理想情況下,您應該重新聲明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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM