我正在尝试根据我是否将特征矩阵传递给它们来重载某些函数,我想为自己制作一些不错的
constexpr
函数以提高可读性。
为此,我决定模仿
std::is_same
上给出的实现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 {};
我告诉自己,很简单:
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 所指出的,这是有区别的。
使用我的解决方案,当
is_eigen<T>
是某种类型的is_eigen<T>::value
或继承自某些
true
的类时,
T
(或
Eigen::Matrix
,在C++11中)是Eigen::Matrix
类。使用 super 的解决方案,只有当
is_eigen<T>::value
是
true
时,您才能知道
T
是
Eigen::Matrix
。当
T
从
Eigen::Matrix
继承时,
is_eigen<T>
是
false
.看看什么更适合您的需求。
std::is_same_v
来实现
constexpr
类型相等性检查。来自
文档的例子:
std::cout << std::is_same_v<int, std::int32_t> << ' '; // ~ true
std::cout << std::is_same_v<int, std::int64_t> << '\n'; // ~ false