2017-05-11 1 views
4

을 통해 상속 템플릿 클래스를 감지하는Metafunction 내가 같이있는 인터페이스가 CRTP

template<typename T> 
class Concrete : public Interface<Concrete<T>, T> 
{ 
    ... 
    using type = typename T; 
} 

내가 확인할 수있는 metafunction을하고 싶습니다 특정 유형이 Interface에서 왔는지 여부

예를 들어

,의 인터페이스는 하나 개의 템플릿 인수를 가지고 말 (따라서이 아이 템플릿 클래스를 생성하지 것)하자 :이 경우

template<typename Concrete> 
class A 
{ 
    ... 
} 

class B : public A<B> 
{ 
    ... 
} 

, 내가 사용할 수 있습니다

template<typename T> 
struct is_A 
{ 
    static bool const value = std::is_base<A<T>, T>::value; 
} 

제 질문은 템플릿 인수가 추가로있는 경우 비슷한 메타 함수를 만드는 가장 좋은 방법입니다.

template<typename T>  
struct is_Interface{} 

이 명확하게하기 위해, 내가

template<template <class> class T>  
struct is_Interface 
{ 
    using dummy_type = void; 
    static bool const value = std::is_base<Interface<T<dummy_type>, dummy_type>, T<dummy_type>>::value; 
} 

을 생산할 수 있지만, 나는 구체적인 유형이 아닌 템플릿 클래스를 전달 뭔가를 싶습니다 것처럼 보일 것입니다.

답변

4

당신은 오버로드 확인을 사용할 수있다 :

template <template <class> class Concrete, class T> 
std::true_type is_Interface_impl(Interface<Concrete<T>, T> *); 

std::false_type is_Interface_impl(...); 

template<typename T> 
struct is_Interface : decltype(is_Interface_impl(std::declval<T*>())) { }; 
포인터 변환이 템플릿 인수 공제에서 허용되는 파생-에 기반

, 즉 is_Interface_impl의 첫 번째 과부하 감지 및 관계를 일치시킬 수 있습니다 방법입니다. 변환이 발생하지 않으면 SFINAE가 적용되고 오버로드 해상도가 다시 vararg 함수로 떨어집니다.

See it live on Coliru!

+0

이것은 정말 멋지다. 내 경우에는 효과가있다! 정말 고마워 – JosephK