类型的 constexpr 检查

les*_*urp 0 c++ sfinae type-traits template-argument-deduction c++14

我正在尝试根据是否将特征矩阵传递给它们来重载某些函数,并且我想让自己变得更好 constexpr函数来提高可读性。

为此,我决定模拟https://en.cppreference.com/w/cpp/types/is_samestd::is_same给出的实现

template<class T, class U>
struct is_same : std::false_type {};

template<class T>
struct is_same<T, T> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)

我肯定地告诉自己,很简单:

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; }
Run Code Online (Sandbox Code Playgroud)

然而,我的特征类型解析为第一个模板特化,而不是第一个(放置一个假人typename U无济于事)。

我也尝试过类似的事情:

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; }
Run Code Online (Sandbox Code Playgroud)

但是对于非 Eigen 类,第一个重载不会解决,并且尝试任何更改都意味着 Eigen 仍会命中错误分支

基本上,即使是 Eigen 类型,我提出的任何默认分支也会被采用。我讨厌 SFINAE :(

sup*_*per 5

您可以使用部分专业化来匹配Eigen::Matrix<...>这样的

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;
Run Code Online (Sandbox Code Playgroud)