2016-09-17 95 views
0

我有一些奇怪的問題實現懶惰分配和添加,如https://eigen.tuxfamily.org/dox/TopicInsideEigenExample.html中所示。在C++中實現懶惰分配時出錯

的代碼是

template<typename Derived> class Base; 
template<typename Derived, typename OtherDerived> class SumOp; 

template<typename Derived, typename OtherDerived> 
class SumOp: public Base<SumOp<Derived, OtherDerived>>{ 
public: 
    Derived & lhs; 
    OtherDerived & rhs; 

    SumOp(Derived & lhs_, OtherDerived & rhs_):lhs(lhs_), rhs(rhs_){} 
    double packet(size_t index, Base<OtherDerived>& src){ 
     return lhs.packet(index)+ rhs.packet(index); 
    } 
}; 
template<typename Derived, typename OtherDerived> 
struct Assign{ 
    static Derived& run(Derived & dst, OtherDerived & src){ 
     size_t length = dst.size(); 
     for (size_t index =0; index < length; index++){ 
      dst.copyPacket(index, src); 
     } 
     return dst; 
    } 
}; 


template<typename Derived> 
class Base{ 
public: 
    Base(){} 
    Derived& derived(){ 
     return *static_cast<Derived*>(this); 
    } 

    const Derived& derived() const{ 
     return *static_cast<const Derived*>(this); 
    } 

    template<typename OtherDerived> 
      SumOp<Derived,OtherDerived> operator+(Base<OtherDerived> & other){ 
       return SumOp<Derived, OtherDerived>(this->derived(), other.derived()); 
    } 

    template<typename OtherDerived> 
     Derived & operator=(Base<OtherDerived>& other){ 
     return Assign<Derived, OtherDerived>::run(derived(), other.derived()); 
    } 
    template<typename OtherDerived> 
      void copyPacket(size_t index, Base<OtherDerived> & other){ 
     derived().writePacket(index, other.derived().packet(index)); 
    } 
}; 


class Vector: public Base<Vector> { 
public: 
    double * data; 
    size_t nRow; 

    Vector(size_t nRow_):nRow(nRow_){ 
     data = (double *)malloc(sizeof(double)*nRow); 
    } 
    ~Vector(){ 
     free(data); 
    } 
    template<typename OtherDerived> 
      Vector& operator=(Base<OtherDerived>& other){ 
     return Base<Vector>::operator=(other); 
    } 
    size_t size(){ 
     return nRow; 
    } 
    void writePacket(size_t index, double src){ 
     data[index] = src; 
    } 
    double packet(size_t index){ 
     return data[index]; 
    } 
}; 

總之,問題的關鍵在於,當我在Vector類,其中編譯器抱怨,我已經通過了左值Base<SumOp<Vector, Vector>>到運營商,而不是SumOp<Vector, Vector>&調用operator=。後者是在撥打operator+時創建的,後者返回SumOp<Vector, Vector>

編譯器錯誤是

no known conversion for argument 1 from ‘SumOp<Vector, Vector>’ to ‘Base<SumOp<Vector, Vector> >&’ 

我不知道爲什麼在本徵的實現是OK,以及如何解決這個問題。

感謝您的幫助。

編輯

當我打電話以下功能

void test_vector(){ 
    Vector a(10), b(10), c(10); 
    for (int i=0;i<10;i++){ 
     a.data[i]=1.0; 
     b.data[i]=1.0; 
    } 
    //This is very it goes wrong 
    c = a+b; 


    for (int i =0 ; i<10;i++){ 
     std::cout << c.data[i] << std::endl; 
    } 

}; 

相剋,會出現問題++ - 6錯誤讀取

invalid initialization of non-const reference of type ‘Base<SumOp<Vector, Vector> >&’ from an rvalue of type ‘Base<SumOp<Vector, Vector> >’ 
    c = a+b; 
     ~^~ 
In file included from /home/ran/Desktop/experiment/PointerMatrix/vector.cpp:6:0: 
/home/ran/Desktop/experiment/PointerMatrix/vector.h:76:21: note: initializing argument 1 of ‘Vector& Vector::operator=(Base<OtherDerived>&) [with OtherDerived = SumOp<Vector, Vector>]’ 
      Vector& operator=(Base<OtherDerived>& other){ 
+0

我似乎無法[轉載](http://coliru.stacked-crooked.com/a/20b82584350dab32)你的問題,既GCC 6.1和叮噹3.8 – WhiZTiM

+0

讓我試用gcc6 –

+0

已經做了〜謝謝非常想提醒 –

回答

3

問題是因爲這些論點你operator函數不是const引用。 operator+返回臨時對象SumOp,該對象不能作爲非const引用傳遞。 (有些編譯器可能支持這種擴展。)

將參數更改爲const &類型應解決此問題。

+0

正是!我以爲我可以繞過const的問題,但我錯了...... –

+0

這將是值得一提的關於這個案件的轉發參考 –