2017-01-06 12 views
3

다른 보기 유형이 있으며, 각각 std::size_t View::dimension 구성원 상수와 typename View::value_type 구성원 유형이 있습니다. FromTo 모두 (is_view<>하여 확인)들이다 및 From의 내용 To에 할당 될 수 있는지SFINAE std :: enable_if 인수

다음 컴파일 형 체크 확인한다. (동일한 차원 및 변환 가능 값 유형).

template<typename From, typename To> 
struct is_compatible_view : std::integral_constant<bool, 
    is_view<From>::value && 
    is_view<To>::value && 
    From::dimension == To::dimension && 
    std::is_convertible<typename From::value_type, typename To::value_type>::value 
> { }; 

is_view<T>는 항상 모든 종류의 T를 들어, std::true_type 또는 std::false_type로 평가하도록한다. 문제는 From 또는 To이보기 유형이 아닌 경우 From::dimension (예 :)이없고, is_compatible_view<From, To>이 컴파일 오류를 발생시키는 것입니다. 이 경우 대신 std::false_type으로 평가되어야합니다.

is_compatible_view은 SFINAE에 std::enable_if과 함께 사용되며 멤버 기능을 사용하지 않도록 설정됩니다. 예를 들어, 뷰 클래스 멤버 함수

struct View { 
    constexpr static std::size_t dimension = ... 
    using value_type = ... 

    template<typename Other_view> 
    std::enable_if_t<is_compatible_view<Other_view, View>> assign_from(const Other_view&); 

    void assign_from(const Not_a_view&); 
}; 

Not_a_view을 가질 수있는 것은 볼 수없고, is_compatible_view<Not_a_view, ...>에서 컴파일 오류가 발생합니다. view.assign_from(Not_a_view())을 호출하면 SFINAE가 적용되지 않고 컴파일러에서 첫 번째 assign_from 함수를 해결하려고하면 컴파일 오류가 발생합니다.

is_compatible_view이 올바르게 작동하려면 어떻게해야합니까? C++에서는 std::conjunction<...>이 이것을 허용합니까?

답변

4

한 가지 접근법은 유형 특성의 다른 부분이 이미 사실임을 확인할 때까지 std::conditional과 같은 것을 사용하여 유형 특성 일부의 평가를 지연합니다.

즉 : 나는 conditional_t::type을 모두 사용하고

// this one is only valid if From and To are views 
template <class From, class To> 
struct is_compatible_view_details : std::integral_constant<bool, 
    From::dimension == To::dimension && 
    std::is_convertible<typename From::value_type, typename To::value_type>::value 
> { };   

// this is the top level one 
template<typename From, typename To> 
struct is_compatible_view : std::conditional_t< 
    is_view<From>::value && is_view<To>::value, 
    is_compatible_view_details<From, To>, 
    std::false_type>::type 
{ }; 

참고. is_compatible_view_detailsFromTo 모두보기 인 경우에만 인스턴스화됩니다.


유사한 방식으로 인해 단락의 유사 평가가 지연되는 위의와 std::conjunction을 사용하는 것입니다 :

template <class From, class To> 
struct is_compatible_view : std::conjunction_t< 
    is_view<From>, 
    is_view<To>, 
    is_compatible_view_details<From, To> 
    > 
{ }; 

어느 쪽이든, 당신은 세부 사항을 당겨해야합니다.


세 번째 방법은 전문화로 enable_if_t을 사용하는 것입니다 :에서 enable_if_t의 표현 중 하나가 잘못 형성된 경우 여기

template <class From, class To, class = void> 
struct is_compatible_view : std::false_type { }; 

template <class From, class To> 
struct is_compatible_view<From, To, std::enable_if_t< 
    is_view<From>::value && 
    is_view<To>::value && 
    From::dimension == To::dimension && 
    std::is_convertible<typename From::value_type, typename To::value_type>::value>> 
: std::true_type { }; 

, SFINAE가 맞이할 우리는 차를 사용 템플릿은 false_type입니다.

+0

실제로 첫 번째 스 니펫에':: type'의 요점이 표시되지 않습니다.또한, 유즈 케이스에 따라'From :: value_type' 등의 에러를 즉각적인 컨텍스트로 끌어들이는'enable_if_compatible_view' 앨리어스 템플릿을 만드는 것으로 충분할 수도 있습니다. –