繁体   English   中英

重载 function 调用运算符 () 用于模板 object 的索引和分配

[英]Overloading function call operator () for indexing and assignments of a template object

我正在尝试为矩阵数据结构创建一个模板,并且我希望以简洁直观的方式来索引和分配元素(即'A(i,j)'返回一个元素和'A(i,j)= x ' 给这个元素赋值。)

基于其他论坛主题,我看到通过引用返回数组元素,函数/运算符可以以这种方式返回和更改该元素。

template <typename T, int Rows, int Cols>
    struct Matrix {
        private:
        public:
            const int rows = Rows; //number of rows
            const int cols = Cols; //number of columns
            T data[Rows*Cols];     //contents of matrix

            //Single element indexing and assigment
            T& operator() (int i, int j) {
                return data[ (i-1)*(this->cols) + j ];
            }
    };

int main(){
    const int m = 3;
    const int n = 4;
    Matrix<float, m, n> A;

    for (int i = 0; i < A.rows; i++) {
        for (int j = 0; j < A.cols; j++) {
            A(i,j) = 3.14;
        }
    }

    return 0;
}

当我尝试使用显式类型的结构(在本例中为 int)而不是模板时,这非常有效,但是现在我使用的是模板,赋值 'A(i,j) = x' 具有修改索引的效果'i' 和 'j' 通常会破坏循环并导致分段错误。

有谁知道为什么会发生这种情况,如果我能做些什么来达到预期的结果?

我对 c++ 相当陌生,所以如果我反对该语言的最佳实践,请随时告诉我

用于索引data的公式不正确。

更新您的 function 以始终返回data[0]但打印索引。 output 将清楚地表明您没有使用正确的索引。

T& operator() (int i, int j) {
    int index = (i-1)*(this->cols) + j;
    std::cout << "Index: " << index << std::endl;
    
    return data[0];  // This is wrong but that's not the
                     // purpose of this suggested change.
}

有用的链接:如何调试小程序

PS正确的索引是i*(this->cols) + j

赋值A(i,j) = x具有修改索引ij的效果,这通常会破坏循环并导致分段错误。

如果我在A(i,j) = 3.14;之前和之后直接打印ij 价值观以我不清楚的方式变化。 例如在第一次调用后, j从 0 变为 1078523331

这意味着您正在破坏 memory 写入越界的数组元素会做到这一点。

您的数组是 0 索引的。 您的ij变量从 0 开始。但是您从i值中减去-1 那么,当您尝试在计算中使用(i-1)来获取数组索引时,您认为会发生什么?

好吧,让我们找出 - 您尝试访问的第一个元素是A(0,0) ,所以:

  data[ (i-1)*(this->cols) + j ]
= data[ (0-1)*(4) + 0 ]
= data[ (-1)*(4) + 0 ]
= data[ -4 + 0 ]
= data[ -4 ]

索引-4处没有数组元素! 您正在返回对 memory 的引用,该引用位于data[]数组之前4*sizeof(T)个字节。

要解决此问题,您需要将计算更改为此:

(i * this->cols) + j

现在,对于A(0,0) (以及所有其他输入为0 <= i < rows0 <= j < cols ),结果将是正确的:

  data[ (i * this->cols) + j ]
= data[ (0 * 4) + 0 ]
= data[ 0 + 0 ]
= data[ 0 ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM