constexpr 类型检查

问题描述 投票:0回答:3

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

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 :(

c++ c++14 sfinae typetraits template-argument-deduction
3个回答
6
投票

你可以像这样使用偏特化来匹配一个

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;

2
投票

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

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
.

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


0
投票
这个问题提到了 C++14,但请注意,从 C++17 开始,您可以使用

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
    
© www.soinside.com 2019 - 2024. All rights reserved.