2016-07-12 3 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, 을'std :: integral_constant '로 대체하십시오. – Yakk

+0

코드를 컴파일하기 위해 어떤 컴파일러를 사용 했습니까? 광산은'is_S (S {}) '를 호출 할 때 모호한 점을 불평합니다. 두 번째 is_S는 어떻게 더 잘 어울리는가? – Engineerist