I'm trying to overload some function based on whether or not I'm passing an Eigen matrix to them, and I wanted to make myself some nice constexpr
function to improve readability.
For that I decided to emulate the implementation of std::is_same
given on https://en.cppreference.com/w/cpp/types/is_same
template<class T, class U>
struct is_same : std::false_type {};
template<class T>
struct is_same<T, T> : std::true_type {};
And I told myself sure, easy enough:
template <typename T>
bool constexpr is_eigen() { return false; }
template <typename T, typename Eigen::Matrix<typename T::Scalar,
T::RowsAtCompileTime,
T::ColsAtCompileTime,
T::Options,
T::MaxRowsAtCompileTime,
T::MaxColsAtCompileTime>>
bool constexpr is_eigen() { return true; }
However my Eigen types resolve to the first template specialization, not the first (putting a dummy typename U
doesn't help).
I also tried something like:
template <typename T, bool is_it = std::is_same<T,
Eigen::Matrix<typename T::Scalar,
T::RowsAtCompileTime,
T::ColsAtCompileTime,
T::Options,
T::MaxRowsAtCompileTime,
T::MaxColsAtCompileTime>>::value>
bool constexpr is_eigen() { return is_it; }
template <typename T, typename = std::enable_if_t<!std::is_class<T>::value>>
bool constexpr is_eigen() { return false; }
But for non-Eigen classes the first overload doesn't resolve, and trying anything to change that means Eigen will still hit the false branch
Basically, any default branch I come up with gets taken even for Eigen-types. I hate SFINAE :(
You can use partial specialization to match a Eigen::Matrix<...>
like so
template <typename T>
struct is_eigen_impl : std::false_type {};
template <typename T, int... Is>
struct is_eigen_impl<Eigen::Matrix<T, Is...>> : std::true_type {};
template <typename T>
constexpr bool is_eigen = is_eigen_impl<T>::value;