2013-08-21 2 views
6

프리디 케이트를 충족시키는 유형을 포함하는 다른 가변 템플릿을 생성하기 위해 가변 템플릿 (predicate 템플릿 기반)에 전달 된 유형을 필터링 할 수 있는지 알고 싶습니다.매개 변수 팩의 유형 필터링

/** Filter a parameter pack */  
template <template <class> class, 
      template <class...> class, 
      class...> 
struct filter; 
template <template <class> class Pred, template <class...> class Variadic> 
struct filter<Pred, Variadic> : Variadic<> 
{}; 
template <template <class> class Pred, 
      template <class...> class Variadic, 
      class T, class... Ts> 
struct filter<Pred, Variadic, T, Ts...> 
{ 
    // FIXME: this just stops at first T where Pred<T> is true 
    using type = typename std::conditional< 
     Pred<T>::value, 
     Variadic<T, Ts...>, // can't do: Variadic<T, filter<...>> 
     filter<Pred, Variadic, Ts...> >::type; 
}; 

필자는 필터링 된 나머지 형식에서 매개 변수 팩을 "추출"하는 방법을 찾지 못했습니다. 사전에

감사합니다!

답변

6

상당히 간단해야합니다. 핵심은이 같은이 있어야합니다

template <typename...> struct filter; 

template <> struct filter<> { using type = std::tuple<>; }; 

template <typename Head, typename ...Tail> 
struct filter<Head, Tail...> 
{ 
    using type = typename std::conditional<Predicate<Head>::value, 
           typename Cons<Head, typename filter<Tail...>::type>::type, 
           typename filter<Tail...>::type 
          >::type; 
}; 

당신은 단지 Cons<T, Tuple> 필요 std::tuple<T, Args...>T, std::tuple<Args...> 켜지고 (연습으로 왼쪽)를 따라 조건을 통과해야합니다. Cons는 다음과 같이 수 : filter<Args...>::type의 결과는 Brgs...는 술어가 보유하고있는 Args...에서 유형 만 구성된 팩입니다 std::tuple<Brgs...>을 것

template <typename, typename> struct Cons; 

template <typename T, typename ...Args> 
struct Cons<T, std::tuple<Args...>> 
{ 
    using type = std::tuple<T, Args...>; 
}; 

.

+0

아직 이해가되지 않는 부분이 있지만 컴파일러 오류가 도움이되지 않습니다. http://ideone.com/USTnJR 여기에 게시했습니다. 다른 모양을 사용하지 않으려는 경우 원본을 편집하는 것이 적절하지 않은 것 같습니다. – scry

+0

그 버전에는 또 다른 문제가 있습니다.이 버전은 http://ideone.com/eh3Epd입니다. 보시다시피 :: filter 및 Cons의 :: type 멤버는 형식으로 인식되지 않습니다. – scry

+0

@roysc :'Cons'는 튜플에 특화되어야합니다. 이것을 편집하겠습니다. [편집 :] 완료. 기본 템플릿을 수정하여 적절한 기본 케이스를 만들었습니다. –