проверка типа constexpr - PullRequest
       70

проверка типа constexpr

0 голосов
/ 15 мая 2019

Я пытаюсь перегрузить некоторую функцию в зависимости от того, передаю ли я им матрицу Eigen, и я хотел сделать себе какую-нибудь симпатичную 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-типов.Я ненавижу СФИНА: (

Ответы [ 2 ]

4 голосов
/ 15 мая 2019

Вы можете использовать частичную специализацию, чтобы соответствовать 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 голос
/ 15 мая 2019

Если я правильно понимаю, вы пытаетесь получить что-то следующим образом (осторожно: код не проверен)

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.

ps: специализация шаблонов, как и в ответе супер, - это еще один (возможно, лучший) способ сделать почти то же самое.

Но, как указал Jarod42, есть разница.

С моим решением вы получите, что is_eigen<T> (или is_eigen<T>::value, в C ++ 11) равно true, когда T является Eigen::Matrix некоторого типа или класс, который наследуется от некоторого Eigen::Matrix класса.

С помощью решения super вы получите, что is_eigen<T>::value равен true, только если T равен Eigen::Matrix.Когда T наследуется от Eigen::Matrix, is_eigen<T> равно false.

Увидимся, что лучше для ваших нужд.

...