类型的constexpr检查

时间:2019-05-15 16:22:35

标签: c++ c++14 sfinae typetraits template-deduction

我正在尝试根据是否将本征矩阵传递给它们来重载某些函数,并且我想使自己成为一些不错的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; }

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

但是对于非本征类,第一个重载无法解决,并且尝试进行任何更改以使本征仍然会到达假分支

基本上,我提出的任何默认分支甚至都适用于本征类型。我讨厌SFINAE:(

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

如果我理解正确,则您尝试获取以下内容(警告:未经测试的代码)

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指出的那样,存在区别。

通过我的解决方案,当is_eigen<T>是某种类型的is_eigen<T>::value时,您会得出true(或在C ++ 11中为T)是Eigen::Matrix 从某个Eigen::Matrix类继承的类。

使用super的解决方案,只有在is_eigen<T>::valuetrue的情况下,T才是Eigen::Matrix。当TEigen::Matrix继承时,is_eigen<T>false

看看有什么能满足您的需求。