类型的 constexpr 检查

constexpr check of a type

我正在尝试根据是否将特征矩阵传递给它们来重载某些函数,我想为自己制作一些不错的 constexpr 函数以提高可读性。

为此,我决定模仿 https://en.cppreference.com/w/cpp/types/is_same

上给出的 std::is_same 的实现
template<class T, class U>
struct is_same : std::false_type {};

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

我告诉自己,很简单:

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; }

但是我的 Eigen 类型解析为第一个模板特化,而不是第一个(放置虚拟 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; }

但是对于非 Eigen 类,第一个重载没有解决,并且尝试任何改变这意味着 Eigen 仍然会遇到错误的分支

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

您可以像这样使用部分特化来匹配 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;

如果我没理解错,你试图获得如下内容(注意:代码未经测试)

template <typename T>
constexpr std::false_type is_eigen_helper (T const &);

template <typename T, int ... Is>
constexpr std::true_type is_eigen_helper (Eigen::Matrix<T, Is...> const &);

template <typename T>
constexpr auto is_eigen { decltype(is_eigen_helper(std::declval<T>()))::value };

在这种情况下 is_eigen<T> 是一个模板变量,因此需要 C++14。

在 C++11 中,您可以将 is_eigen<T> 定义为类型

template <typename T>
using is_eigen = decltype(is_eigen_helper(std::declval<T>()));

因此您可以使用 is_eigen<T>::value 检查 T 是否是 Eigen::Matrix

p.s.: 模板专业化,如 super 的回答,是另一种(也许更好)做几乎相同事情的方法。

但是,正如 Jarod42 所指出的,这是有区别的。

使用我的解决方案,当 TEigen::Matrix 时,is_eigen<T>(或 is_eigen<T>::value,在 C++11 中)是 true某些类型 继承自某些 Eigen::Matrix class.

的 class

只有当 T 是一个 Eigen::Matrix 时,你才能得到 is_eigen<T>::valuetrue 的 super 解决方案。当 TEigen::Matrix 继承时,is_eigen<T>false

看看什么更适合您的需求。