C++/Eigen -如何传递一般向量作为参数?

dced5bon  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(193)

使用特征3.4.0
我想写一个通用于任何特征向量的函数。
Eigen为任何Eigen对象提供了MatrixBase,但我想明确说明这是一个只包含向量的函数。
例如,我可以编写一个通用的MatrixBase函数,如下所示:

template<Derived>
   typename MatrixBase<Derived>::PlainObject foo(MatrixBase<Derived>& M)
   { // N = operations on M
     // ...
     return N;
   }

我想要的东西大意是:

template<Derived>
   typename VectorBase<Derived>::PlainObject foo(VectorBase<Derived>& M);

我试过:

template<Derived>
   Vector<typename Derived::Scalar, Dynamic> foo(Vector<typename Derived::Scalar>& M);

这行不通
我目前的解决方案是只对函数进行模板化,并使模板明确只使用向量,但这似乎不是最佳实践。

template<VectorX>
   VectorX foo(VectorX M);
iklwldmw

iklwldmw1#

特征库中没有VectorBaseEigen::Vector只是Eigen::Matrix的别名:

template<typename Type , int Size>
using   Eigen::Vector = Matrix< Type, Size, 1 >

所以,如果你想让你的函数只允许Eigen::Vector,那么只需要一个Eigen::Vector函数参数,但是你需要模板参数来匹配Vector的模板参数,例如:

template<typename Type, int Size>
typename Eigen::Vector<Type,Size>::PlainObject foo(Eigen::Vector<Type,Size>& M);
sigwle7e

sigwle7e2#

不幸的是,类型系统不能区分参数声明中的向量和矩阵,Eigen通过使用a set of macros解决了这个问题,如果你尝试使用a set of macros会导致编译错误,我建议使用同样的方法:

template<DerivedVector>
typename Eigen::MatrixBase<Derived>::PlainObject
foo(const Eigen::MatrixBase<DerivedVector>& M)
{ 
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(DerivedVector);
    return N;
}

如果你想要更多的控制,你可以写你自己的静态Assert,特别是现在用C++11,这已经变得简单多了。

template<class Derived>
inline constexpr bool isRowVector(const Eigen::MatrixBase<Derived>&)
{ return Derived::RowsAtCompileTime == 1; }

template<class Derived>
inline constexpr bool isColVector(const Eigen::MatrixBase<Derived>&)
{ return Derived::ColsAtCompileTime == 1; }

template<class Derived>
inline constexpr bool isVector(const Eigen::MatrixBase<Derived>& vec)
{ return isRowVector(vec) || isColVector(vec); }

template<DerivedVector>
typename Eigen::MatrixBase<DerivedVector>::PlainObject
foo(const Eigen::MatrixBase<DerivedVector>& M)
{ 
    static_assert(isVector(M));
    return N;
}

相关问题