Я пытаюсь написать функцию, которая принимает собственные типы фиксированного размера (но на основе скалярного типа, например, float / double). я прочитал http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html но я не могу заставить его работать идеально.
Вот определение функции:
template <typename T>
inline Matrix<T, 3, 3> makeSkewSymmetric(const Matrix<T, 3, 1>& v)
{
Matrix<T, 3, 3> out;
out << 0, -v[2], v[1],
v[2], 0, -v[0],
-v[1], v[0], 0;
return out;
}
Теперь я использую это следующим образом:
Vector3d a(1,2,3);
Matrix3d ass = makeSkewSymmetric(a); // Compiles
Matrix3d ass = makeSkewSymmetric(a + a); // does NOT compile
Я думаю, мне нужно использовать какой-то MatrixBase<Derived>
, но тогда как мне ограничить размер, так как функция имеет смысл только для векторов длины 3.
Редактировать: Я переопределил функцию следующим образом. Это работает, но есть ли лучший способ?
template <typename Derived>
inline Matrix<typename Derived::Scalar, 3, 3> makeSkewSymmetric(const MatrixBase<Derived>& v)
{
BOOST_STATIC_ASSERT(Derived::RowsAtCompileTime == 3 && Derived::ColsAtCompileTime == 1);
Matrix<typename Derived::Scalar, 3, 3> out;
out << 0, -v[2], v[1],
v[2], 0, -v[0],
-v[1], v[0], 0;
return out;
}
Я просто подумал о хорошем способе проверки того, как разработчики Eigen хотят, чтобы вы решили эту проблему. Эйген приходит с cross
функция на MatrixBase
, но эта функция, как и ваша, имеет смысл только для трехмерных векторов — поэтому я выкопал соответствующую часть из источника Eigen3: (ср Eigen/src/Geometry/OrthoMethods.h
)
...
inline typename MatrixBase<Derived>::template cross_product_return_type<OtherDerived>::type
MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3)
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3)
...
и действительно, сам Eigen использует утверждения (хотя и свой собственный вид) для проверки размеров в обобщенных функциях.
Других решений пока нет …