我对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::vector
、Eigen
或类似的解决方案。
提前谢谢。
您可以编写一个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) {
//...
}
这减轻了使其更短的需要。