重载函数调用 operator() 用于模板对象的索引和赋值
Overloading function call operator () for indexing and assignments of a template object
我正在尝试为矩阵数据结构创建一个模板,我希望有一种简洁直观的方式来索引和分配元素(即 'A(i,j)' return 一个元素和 'A(i,j)=x' 给这个元素赋值。)
根据其他论坛帖子,我看到通过引用 return 数组元素,function/operator 可以 return 并以这种方式更改该元素。
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
的公式不正确。
始终将您的函数更新为 return data[0]
,但打印索引。输出将清楚地表明您没有使用正确的索引。
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.
}
有用link:How to debug small programs
PS 正确的索引是i*(this->cols) + j
.
the assignment A(i,j) = x
has the effect of modifying the indices i
and j
which usually breaks the loops and causes segmentation faults.
if I print i
and j
directly before and after A(i,j) = 3.14;
the values change in ways that aren't clear to me. For instance after the first call, j
changes from 0 to 1078523331
这意味着你正在破坏记忆。写入一个 超出范围 的数组元素将执行此操作。
您的数组是从 0 开始索引的。您的 i
和 j
变量从 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
处没有数组元素!您正在返回对位于 data[]
数组 前 4*sizeof(T)
字节 的内存的引用。
要解决此问题,您需要将计算更改为:
(i * this->cols) + j
现在,A(0,0)
(以及所有其他输入 0 <= i < rows
和 0 <= j < cols
)的结果将是正确的:
data[ (i * this->cols) + j ]
= data[ (0 * 4) + 0 ]
= data[ 0 + 0 ]
= data[ 0 ]
我正在尝试为矩阵数据结构创建一个模板,我希望有一种简洁直观的方式来索引和分配元素(即 'A(i,j)' return 一个元素和 'A(i,j)=x' 给这个元素赋值。)
根据其他论坛帖子,我看到通过引用 return 数组元素,function/operator 可以 return 并以这种方式更改该元素。
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
的公式不正确。
始终将您的函数更新为 return data[0]
,但打印索引。输出将清楚地表明您没有使用正确的索引。
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.
}
有用link:How to debug small programs
PS 正确的索引是i*(this->cols) + j
.
the assignment
A(i,j) = x
has the effect of modifying the indicesi
andj
which usually breaks the loops and causes segmentation faults.if I print
i
andj
directly before and afterA(i,j) = 3.14;
the values change in ways that aren't clear to me. For instance after the first call,j
changes from 0 to 1078523331
这意味着你正在破坏记忆。写入一个 超出范围 的数组元素将执行此操作。
您的数组是从 0 开始索引的。您的 i
和 j
变量从 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
处没有数组元素!您正在返回对位于 data[]
数组 前 4*sizeof(T)
字节 的内存的引用。
要解决此问题,您需要将计算更改为:
(i * this->cols) + j
现在,A(0,0)
(以及所有其他输入 0 <= i < rows
和 0 <= j < cols
)的结果将是正确的:
data[ (i * this->cols) + j ]
= data[ (0 * 4) + 0 ]
= data[ 0 + 0 ]
= data[ 0 ]