문제

2015-01-08 1 views
0

나는 종류의 템플릿 팩이 단항 술어의 팩 UnaryPredicates...에 의해 multipartitioned됩니다 형태 때문에문제

MultipartitionWithUnaryPredicates<Pack<Args...>, UnaryPredicates...>::type 

에 사용되는 메타 기능 MultipartitionWithUnaryPredicates을 쓰고 있어요 단항 술어의 순서대로 파티션이 나열됩니다. 당신이 내 말은, 단지 (제대로 작동하는) 아래의 코드에서 main()을 체크 아웃 무엇인지 확실하지 않은 경우 :

#include <iostream> 
#include <type_traits> 
#include <typeInfo> 

template <template <typename> class, typename, typename, typename> struct Helper; 

template <template <typename> class UnaryPredicate, template <typename...> class P, typename... Types1, typename... Types2> 
struct Helper<UnaryPredicate, P<>, P<Types1...>, P<Types2...>> { 
    using type = P<Types1..., Types2...>; 
    using head = P<Types1...>; 
    using tail = P<Types2...>; 
}; 

template <template <typename> class UnaryPredicate, template <typename...> class P, typename First, typename... Rest, typename... Types1, typename... Types2> 
struct Helper<UnaryPredicate, P<First, Rest...>, P<Types1...>, P<Types2...>> : std::conditional<UnaryPredicate<First>::value, 
     Helper<UnaryPredicate, P<Rest...>, P<Types1..., First>, P<Types2...>>, 
     Helper<UnaryPredicate, P<Rest...>, P<Types1...>, P<Types2..., First>> 
    >::type {}; 

template <typename, template <typename> class> struct PartitionWithUnaryPredicate; 

template <template <typename> class UnaryPredicate, template <typename...> class P, typename... Ts> 
struct PartitionWithUnaryPredicate<P<Ts...>, UnaryPredicate> : Helper<UnaryPredicate, P<Ts...>, P<>, P<>> {}; 

template <typename, template <typename> class...> struct MultipartitionWithUnaryPredicates; 

template <typename Pack, template <typename> class UnaryPredicate> 
struct MultipartitionWithUnaryPredicates<Pack, UnaryPredicate> : PartitionWithUnaryPredicate<Pack, UnaryPredicate> {}; 

template <typename, typename> struct Join; 

template <template <typename...> class P, typename... Types1, typename... Types2> 
struct Join<P<Types1...>, P<Types2...>> { 
    using type = P<Types1..., Types2...>; 
}; 

//template <template <typename, template <typename> class> class Pack, typename... Ts> 
//struct JoinSpecial : Join<typename Pack::head, typename MultipartitionWithUnaryPredicates<typename Pack::tail, Ts...>::type> {}; 

template <typename Pack, template <typename> class First, template <typename> class... Rest> 
struct MultipartitionWithUnaryPredicates<Pack, First, Rest...> : Join<typename PartitionWithUnaryPredicate<Pack, First>::head, typename MultipartitionWithUnaryPredicates<typename PartitionWithUnaryPredicate<Pack, First>::tail, Rest...>::type> {}; 
// The above can be improved, since PartitionWithUnaryPredicate<Pack, First> is being computed twice. 

// ----------------------------------------------------------------------------------------------------------------------------------------------- 
// Testing: 

template <typename...> struct Pack {}; 

template <typename Last> 
struct Pack<Last> { 
    static void print() {std::cout << typeid(Last).name() << std::endl;} 
}; 

template <typename First, typename ... Rest> 
struct Pack<First, Rest...> { 
    static void print() {std::cout << typeid(First).name() << ' '; Pack<Rest...>::print();} 
}; 

struct Thing {}; 
struct Blob { Blob(Blob&&){} }; // Copy constructor deleted. 
struct Object {}; 
enum MyEnum {x, y, z}; 
enum HerEnum {xx, yy, zz}; 

int main() { 
    MultipartitionWithUnaryPredicates<Pack<int, Thing, double, short, Blob, char, MyEnum, long, Object, float, HerEnum>, 
     std::is_integral>::type b; 
    b.print(); // int short char long Thing double Blob MyEnum Object float HerEnum 

    MultipartitionWithUnaryPredicates<Pack<int, Thing, double, short, Blob, char, MyEnum, long, Object, float, HerEnum>, 
     std::is_integral, std::is_enum>::type c; 
    c.print(); // int short char long MyEnum HerEnum Thing double Blob Object float 

    MultipartitionWithUnaryPredicates<Pack<int, Thing, double, short, Blob, char, MyEnum, long, Object, float, HerEnum>, 
     std::is_integral, std::is_enum, std::is_arithmetic>::type d; 
    d.print(); // int short char long MyEnum HerEnum double float Thing Blob Object 

    MultipartitionWithUnaryPredicates<Pack<int, Thing, double, short, Blob, char, MyEnum, long, Object, float, HerEnum>, 
     std::is_integral, std::is_enum, std::is_arithmetic, std::is_member_pointer, std::is_copy_constructible>::type e; 
    e.print(); // int short char long MyEnum HerEnum double float Thing Object Blob 
} 

을 문제는 위의 코드를 수정하기 위해 노력하고있다.

PartitionWithUnaryPredicate<Pack, First> 

두 번 계산됩니다. 나는 한 번만 사용하는 JoinSpecial을 정의하려고합니다. 하지만 올바른 구문을 가져올 수 없습니다.

template <template <typename, template <typename> class> class Pack, typename... Ts> 
struct JoinSpecial : Join<typename Pack::head, typename MultipartitionWithUnaryPredicates<typename Pack::tail, Ts...>::type> {}; 

이 컴파일되지 않습니다. 템플릿 유형 PartitionWithUnaryPredicatetemplate <typename, template <typename> class> class 유형입니까?

는 업데이트 : 문헌 : Angew의 팁 덕분에, 지금 올바른 구문을 가지고 :

template <template <typename, template <typename> class> class P, typename Pack, template <typename> class Pred, template <typename> class... Ts> 
struct JoinSpecial : Join<typename P<Pack, Pred>::head, typename MultipartitionWithUnaryPredicates<typename P<Pack, Pred>::tail, Ts...>::type> {}; 

template <typename Pack, template <typename> class First, template <typename> class... Rest> 
struct MultipartitionWithUnaryPredicates<Pack, First, Rest...> : JoinSpecial<PartitionWithUnaryPredicate, Pack, First, Rest...> {}; 

이제 모든 것이 제대로 작동 - 내 처음 내가 외모를 상당히 말을해야하는 템플릿 템플릿 템플릿을 사용하여 추한.

답변

2

JoinSpecial의 정의에서 Pack은 클래스 템플릿입니다. 그런 다음 템플릿 인수를 Join으로 지정하면 typename Pack::headtypename Pack::tail이됩니다. 그러나 Pack은 템플릿이 아니며 클래스가 아닙니다. — Pack에 대한 템플릿 인수를 제공해야합니다.

+0

좋아, 내가 필요로하는 정확한 sytax이 때문에'템플릿 <템플릿 <유형 이름, 템플릿 클래스> 클래스 P, 유형 이름 팩, 템플릿 클래스 Pred를 가산, 템플릿 클래스 ... TS> 구조체 JoinSpecial : 가입 <유형 이름 P :: head, typename MultipartitionWithUnaryPredicates :: 꼬리말, Ts ...> :: 유형> {};'휴! 템플릿 템플릿 템플릿. – prestokeys