2017-03-15 16 views
4

템플릿 템플릿 클래스의 인터페이스를 검사 만합니다 그 일을하는 좋은 방법을 알 수는 없습니다.어떻게 템플릿 템플릿 매개 변수는에 정의 된 유형 <code>type</code> (예를 들어 <code>std::remove_reference</code>는 <code>type</code> 멤버 타입 별칭이있다)를 가지고 여부에 따라 SFINAE와 템플릿 클래스를 오버로드려고

예를 들어, 나는

template <template <typename...> class Trait> 
using EnableIfHasTypeMember = std::void_t<Trait::type>; 

template <template <typename...> class Trait, typename OtherStuff, 
      EnableIfHasTypeMember<Trait>* = nullptr> 
class Something { ... } 

을하고 싶어하지만 나에게 컴파일러 오류를 제공합니다. 템플릿 템플릿 매개 변수의 인터페이스를 검사 할 수있는 방법이 있습니까?

답변

9

내가 원하는 것을 정확히 이해했다면, 당신이 보여준 일반성 수준으로는 불가능합니다. 특수화에 따라 다를 수 있기 때문에 인스턴스화 된 인수를 모르는 경우 템플릿에 유형 멤버 유형 별칭이 있는지 여부를 알 수 없습니다. 예 :

template <typename T> 
struct my_trait 
{ 
    using type = int; 
}; 

template <> 
struct my_trait<double> {}; 

EnableIfHasTypeMember의 경우 어떻게 동작합니까? 그렇기 때문에 템플릿이 인스턴스화 될 때까지 템플릿의 내용을 추론 할 수 없습니다.

그것은 다른 종류의 T에 대한 my_trait<T>의 모든 인스턴스 생성이 서로에서 구별 유형을 염두에 두어야 할이 같은 상황에 도움이됩니다. 유형 간에는 실제 관계가 없습니다. 그것들은 재사용되는 일반적인 구현체를 작성하는 능력을 인정하는 공통 템플리트에서 시작되었지만 인스턴스화 된 구체 유형은 완전히 분리되어 있습니다.

1

@Jason R은 정확합니다. 클래스 템플릿 수준에서는이 작업을 수행 할 수 없습니다.

type 회원으로 클래스 템플릿을 검색하려면 특정 유형을 얻으려는 인수를 제공해야합니다.

적응 an example

// primary template handles types that have no nested ::type member: 
template< class, class = std::void_t<> > 
struct has_type_member : std::false_type { }; 

// specialization recognizes types that do have a nested ::type member: 
template< class T > 
struct has_type_member<T, std::void_t<typename T::type>> : std::true_type { }; 

// specialization recognizes class templates that do have a nested ::type member: 
template< template< class ... > class T, class ... Args > 
struct has_type_member<T<Args...>, std::void_t<typename T<Args...>::type>> : std::true_type { };