2013-02-08 76 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

相关问题