2016-07-12 4 views
1

boost :: hanaで楽しくなる。私は別のタイプのタグのように機能し、特定のネストされたタイプのために確認したいので、私は花:: when_valid例から借りて、そのSFINAE対応専門と一緒にクラスis_S定義された:boost/hanaで特定のネストされた型/タグを確認する

#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 

花哲学の値型計算に合わせて、同じ小切手を書くの単純/短い/より簡潔な方法はありますか?

答えて

3

は、ここで私が書くかもしれないものです:

#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; 
} 
+0

私はその簡潔さを本当に愛しています。ドキュメントはよく書かれており、非常に役立ちますが、実際にはハナのイディオムの感覚を得るにはしばらく時間がかかります。 – Engineerist

1

私はで誘惑さwoukd:

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 {}; } 
+0

不完全なクラスであることを表示されたときにこれが私の最後にコンパイルされません。 – Engineerist

+0

@eng heh、 'when <>'を 'std :: integral_constant ' – Yakk

+0

に置き換えます。どのコンパイラを使ってコードをコンパイルしましたか?鉱山はis_S(S {})を呼び出す際にあいまいさを訴えます。 2番目のis_Sはどのようにしてより良くマッチしますか? – Engineerist

関連する問題