Проверка определенного вложенного типа / тега с помощью Boost Hana

Весело с boost :: hana. Я хочу проверить наличие определенного вложенного типа, который действует как тег другого типа, поэтому я позаимствовал из примера hana :: when_valid и определил класс is_S вместе с его специализацией с поддержкой SFINAE:

#include <iostream>

#include <boost/hana/core/when.hpp>
namespace hana = boost::hana;

#define V(x) std::cout << x << std::endl

struct S_tag { };

struct S {
using tag = S_tag;
};

struct T {
using tag = int;
};

template< typename T, typename = hana::when< true > >
struct is_S {
static constexpr bool value = false;
};

template< typename T >
struct is_S< T, hana::when_valid< typename T::tag > > {
static constexpr bool value = std::is_same<
typename T::tag, S_tag >::value;
};

int main () {
std::cout << "is_S (    S { }) = "; V ((is_S< S >::value));
std::cout << "is_S (    T { }) = "; V ((is_S< T >::value));
std::cout << "is_S (float { }) = "; V ((is_S< float >::value));

return 0;
}

Это печатает:

$ clang++ -std=c++1z sfinae.cpp && ./a.out | c++filt
is_S (    S { }) = 1
is_S (    T { }) = 0
is_S (float { }) = 0

Существует ли более простой / короткий / более лаконичный способ написания одной и той же проверки в соответствии с вычислением типа значения философии ханы?

1

Решение

Вот что я мог бы написать:

#include <boost/hana.hpp>
#include <iostream>
namespace hana = boost::hana;struct S_tag { };
struct S { using tag = S_tag; };
struct T { using tag = int; };

auto tag_of = [](auto t) -> hana::type<typename decltype(t)::type::tag> {
return {};
};

auto is_S = [](auto t) {
return hana::sfinae(tag_of)(t) == hana::just(hana::type<S_tag>{});
};

int main() {
std::cout << "is_S (    S { }) = " << is_S(hana::type<S>{})() << std::endl;
std::cout << "is_S (    T { }) = " << is_S(hana::type<T>{})() << std::endl;
std::cout << "is_S (float { }) = " << is_S(hana::type<float>{})() << std::endl;
}
3

Другие решения

Я бы соблазнился:

template<class...T>
constexpr std::integral_constant<bool,false> is_S(T const&...){ return {}; }
template<class T>
constexpr
std::integral_constant<bool,std::is_same<typename T::tag,S_tag>{}>
is_S(T const&){ return {}; }
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector