I wrote the following template to check if a triangle is degenerate:
template<typename Derived>
bool nondegenerate(const Eigen::PlainObjectBase<Derived>& triangle) {
typedef typename Derived::Scalar scalarType;
if (triangle.cols() == 2) {
Eigen::Matrix<scalarType, 1, 2> v1 = triangle.row(1) - triangle.row(0);
Eigen::Matrix<scalarType, 1, 2> v2 = triangle.row(2) - triangle.row(0);
return v1(0)*v2(1) - v1(1)*v2(0);
} else if (triangle.cols() == 3) {
Eigen::Matrix<scalarType, 1, 3> v1 = triangle.row(1) - triangle.row(0);
Eigen::Matrix<scalarType, 1, 3> v2 = triangle.row(2) - triangle.row(0);
return v1.cross(v2).norm();
} else {
std::cerr << "Undefined input." << std::endl;
return false;
}
}
The above code works fine if I call nondegenerate
with a matrix of type Eigen::MatrixXi
:
Eigen::MatrixXi triangle;
triangle.resize(3,2);
triangle << 1,2,3,4,5,6;
nondegenerate(triangle);
However, if I replace the above dynamic size matrix with a fixed size matrix:
Eigen::Matrix<int, 3, 2> triangle;
triangle << 1,2,3,4,5,6;
nondegenerate(triangle);
It reports compile errors:
/usr/local/include/eigen3/Eigen/src/Core/AssignEvaluator.h:833:3: error: static_assert failed due to requirement '(int(Eigen::internal::size_of_xpr_at_compile_time<Eigen::Matrix<int, 1, 3, 1, 1, 3> >::ret) == 0 && int(Eigen::internal::size_of_xpr_at_compile_time<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > >::ret) == 0) || ((int(Matrix<int, 1, 3, 1, 1, 3>::RowsAtCompileTime) == Eigen::Dynamic || int(CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >::RowsAtCompileTime) == Eigen::Dynamic || int(Matrix<int, 1, 3, 1, 1, 3>::RowsAtCompileTime) == int(CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >::RowsAtCompileTime)) && (int(Matrix<int, 1, 3, 1, 1, 3>::ColsAtCompileTime) == Eigen::Dynamic || int(CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >::ColsAtCompileTime) == Eigen::Dynamic || int(Matrix<int, 1, 3, 1, 1, 3>::ColsAtCompileTime) == int(CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >::ColsAtCompileTime)))' "YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES" EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(ActualDstTypeCleaned,Src) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/eigen3/Eigen/src/Core/util/StaticAssert.h:190:3: note: expanded from macro 'EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE' EIGEN_STATIC_ASSERT(
^~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/eigen3/Eigen/src/Core/util/StaticAssert.h:33:40: note: expanded from macro 'EIGEN_STATIC_ASSERT' #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG); ^ ~ /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:732:17: note: in instantiation of function template specialization 'Eigen::internal::call_assignment_no_alias<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> >, Eigen::internal::assign_op<int, int> >' requested here internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar,typename OtherDer... ^ /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:537:7: note: in instantiation of function template specialization 'Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >::_set_noalias<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > >' requested here _set_noalias(other); ^ /usr/local/include/eigen3/Eigen/src/Core/Matrix.h:377:9: note: in instantiation of function template specialization 'Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >::PlainObjectBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > >' requested here : Base(other.derived()) ^ testEigenIgl.cpp:1052:42: note: in instantiation of function template specialization 'Eigen::Matrix<int, 1, 3, 1, 1, 3>::Matrix<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<int, int>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false>, const Eigen::Block<const Eigen::Matrix<int, 3, 2, 0, 3, 2>, 1, 2, false> > >' requested here Eigen::Matrix<scalarType, 1, 3> v1 = triangle.row(1) - triangle.row(0); ^ testEigenIgl.cpp:1082:7: note: in instantiation of function template specialization 'nondegenerate<Eigen::Matrix<int, 3, 2, 0, 3, 2> >' requested here
How can I fix the template to accept both dynamic and fixed size matrices?
Thanks!
if constexpr
in such case. If you useC++14
or earlier versions then you ought to use SFINAE based techniques and overload the method for different cases. – ALX23z