2013-02-08 71 views
1

我想我不太瞭解引用背後的內容,我很樂意多瞭解這些內容。調用操作符()「函數調用」返回對數組元素的引用

我正在寫一個數學「矢量」類來做數值模擬的基本線性代數。在我確信不再使用外部庫之前,我正在使用Eigen。我的問題很簡單:

  • 我聲明向量並設置其類型Scalar(這些是雙打)的3個組件。當我重載操作符時,我可以用我的向量來做數學運算,但這超出了我的問題範圍。
  • 我想通過函數調用運算符(),因爲我是用徵來訪問我的對象的第i個分量:myVector(0) = 0.0 ;Scalar d = myVector(0)+1.0 ;

據我引用的瞭解,這個解決方案應該是工作:

class mtnVector { 
public: 
    typedef double Scalar; 
    Scalar data [3]; 
    (setters, math, etc...) 
    inline Scalar & operator() (const int i) const { 
     return data[i] ; 
    } 
}; 

但G ++說,它不喜歡我實現它的方式和的證明了I S ***在引用: Vector.h:185: error: invalid initialization of reference of type ?double&? from expression of type ?const double?

什從我的觀點來看,非常奇怪的是,如果包含數據的數組是動態設置的(Scalar * data)(帶有new運算符),則該類代碼編譯正常。但我沒有看到動態設置數據持有者的觀點。

我沒有得到任何需要const來重載函數調用操作符,但我接受它。

回答

2

您的operator()宣佈爲const。這意味着調用函數不應該最終修改對象。該函數通過非const引用返回此對象的成員,這將允許任何稱爲operator()的人修改對象的內部。顯然這會很愚蠢,所以編譯器不允許它。如果你要參考從const成員函數返回一個成員,你需要做的是參考const

inline const Scalar& operator() (const int i) const { 
    return data[i] ; 
} 

您可能需要同時提供const和非const版的功能,其中一個返回const Scalar&,另一個返回Scalar&(這是how the standard library containers do it)。

你很想用operator()來做這件事。您的表達myVector(0)看起來更自然,因爲您可以通過重載operator[]代替myVector[0]

此外,你應該忽略誰說服你,你不應該使用外部庫。 Eigen尤其是一個非常成熟和經過徹底測試的圖書館。除非你有充分的理由,否則你應該使用它。

+0

謝謝你的回答。我仍然有一些麻煩來獲得常量的範圍。外部庫問題是因爲我不是計算機人員,我使用C++來進行數值模擬,而且我周圍的人或多或少地被Fortran 90和塵土飛揚的「數值收斂」所困住。什麼是「外部」是魔鬼,我處理它:) ... – Pascail 2013-02-08 16:02:21

+0

把'const'放在函數聲明的末尾,說這個函數只能在'const'對象上調用。這意味着對象應該是不變的。如果你的'const'成員函數以任何方式修改該對象,編譯器會發出抱怨。你的函數不直接做它,但它* *通過非''constst'引用返回對象的一部分的引用。這允許調用函數的人修改對象的內部部分,即使對象是'const'。這不好!所以你的函數,如果它是'const',*必須*只返回const引用。 – 2013-02-08 16:08:06

+1

嗯,我實現了這兩個,它的作用就像一個魅力:)我可以在Eigen或我自己的矢量/矩陣之間切換,並且我會繼續使用Eigen並保留自己的類作爲備份解決方案,當人們會說我當我使用外部庫時做錯誤的代碼...我現在明白爲什麼g ++拋出所有這些錯誤。謝謝@sftrabbit !!!! – Pascail 2013-02-08 17:27:01