抽象掉C++中的嵌套循环



我对C++比较陌生,正在构建一个矩阵类,用于执行常见的线性代数运算。hpp:的一些片段

template<const int rows, const int columns, typename T=float>
struct Matrix3D
{
const int shape[2] = {rows, columns};

float content[rows][columns]{};

Matrix3D()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
this->content[i][j] = 0.;
}
}
}

explicit Matrix3D(const T (&arr)[rows][columns])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
this->content[i][j] = arr[i][j];
}
}
}

bool operator==( const Matrix3D<rows, columns> &mat ) const noexcept
{
int equal = 0;

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
equal += this->content[i][j] == mat.content[i][j];
}
}
return  equal == rows * columns;
}

bool operator!=( const Matrix3D<rows, columns> &mat ) const noexcept
{
int equal = 0;

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
equal += this->content[i][j] == mat.content[i][j];
}
}
return  equal != rows * columns;
}
...
};

你会明白:对于我需要操作矩阵对象的几乎所有操作,我需要在每个方法中使用这些双循环。

有没有一种方法可以将其抽象为static方法,并将核心循环表达式作为参数传递?值得注意的是,我的解决方案必须与CUDA兼容,这意味着我不能使用std::vectorEigen或类似的解决方案。

提前谢谢。

您可以编写一个for_each_element成员模板:

template <typename F>
void for_each_element(F f) {
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
f(i,j);
}
}
}

例如,operator!=可以写成:

bool operator!=( const Matrix3D<rows, columns> &mat ) const noexcept
{
int equal = 0;
for_each_element( [&](int i,int j) {                                  
equal += this->content[i][j] == mat.content[i][j];
});
return  equal != rows * columns;
}

然而,例如operator==就是一个很好的例子,说明了为什么这不是最好的主意:与其循环遍历所有元素,不如在遇到不相等的元素时立即停止。for_each_element不允许您这样做(至少在当前形式下不允许(。正如其他人在评论中所建议的那样,对于矩阵,你应该";"抽象";第二个维度,通过使用1d数组加上索引转换:

T& get(size_t i,size_t j) { return this->content[i*columns + j]; }

其中CCD_ 10是适当大小的1d阵列。

然后,您可以将大多数循环写入

for (auto& element : content) {
//...
}

这减轻了使其更短的需要。

最新更新