Eigen文档中填充了一些示例,说明了如何编写接受矩阵的通用函数:
template <typename Derived>
void print_cond(const MatrixBase<Derived>& a)
使用MatrixBase
而不是Matrix
的原因是所有密集的特征矩阵表达式都来自MatrixBase
。所以,例如,如果我传递一个矩阵块
print_cond ( A.block(...));
然后使用签名const MatrixBase<Derived>& a
避免创建临时。相反,如果我们已经使用签名声明了该函数
template <typename T, int rows, int cols>
void print_cond(const Matrix<T,rows,cols>& a)
那么Eigen必须在将块类型传递给函数之前将其转换为矩阵,这意味着必须创建一个不必要的临时值。
如果这种理解不正确,请纠正我...
考虑到这一点,第二种方法的好处之一是我们可以对矩阵的维度进行编译时间检查(假设它们是固定的,而不是动态的)。
我在文档中找不到的是第一种方法的一般性(有助于避免临时创建)的示例,但它包含矩阵类型和维度的时间检查。有人可以告诉我该怎么做?
为了完整起见,Marc和ggael建议这样的事情
#include <iostream>
#include "Eigen/Dense"
using namespace Eigen;
using T = double;
const int rows = 5;
const int cols = 3;
template<typename Derived>
void print_cond(const MatrixBase <Derived> &a) {
/* We want to enforce the shape of the input at compile-time */
static_assert(rows == Derived::RowsAtCompileTime);
static_assert(cols == Derived::ColsAtCompileTime);
/* Now that we are guaranteed that we have the
* correct dimensions, we can do something... */
std::cout << a;
}
int main() {
print_cond(Matrix<T, rows, cols>::Ones());
/* These will not compile */
// print_cond(Matrix<T, rows + 1, cols>::Ones());
// print_cond(Matrix<T, rows, cols + 1>::Ones());
// print_cond(Matrix<T, rows + 1, cols + 1>::Ones());
return 0;
}