2016-06-23 1 views
4

유형이 원래 인스턴스화 된 템플릿을 검색하려면 어떻게해야합니까?유형이 인스턴스화 된 템플릿 검색

다음 작업을 수행 할 싶습니다

struct Baz{}; 
struct Bar{}; 

template <typename T> 
struct Foo {}; 

using SomeType = Foo<Bar>; 

template <typename T> 
using Template = get_template<SomeType>::template type<T>; 

static_assert(std::is_same<Foo<Baz>, Template<Baz>>::value, ""); 

가 나는 부분 특수화를 통해이를 달성 할 수 알고 있지만 내가 그것을 사용하려는 모든 템플릿 get_template을 전문으로하는 저를 강제로 :

이 문제를 해결하는 방법이
template <typename T> 
struct get_template; 

template <typename T> 
struct get_template<Foo<T>> 
{ 
    template <typename X> 
    using type = Foo<X>; 
}; 

live example

있습니까?

+0

가능한 [부모 유형 가져 오기] (http://stackoverflow.com/questions/31429363/get-the-type-of-a-parent) –

+3

가능한 예는 약간의 인위적인 내용입니다. 별칭을 사용합니다. "SomeType"은 이미 "Foo "(static_assert (std :: is_same > :: 값, ");)과 동일합니다. 아마도'Foo' 부분 만 복구하려고 할 것입니다. 다른 유형으로 인스턴스화하고 싶기 때문입니다. – AndyG

+0

@AndyG 예 결국 다른 유형으로 인스턴스화하고 싶습니다. 질문을 편집했습니다. –

답변

4

당신은 template template parameter (유형의 번호와 템플릿을 위해 일해야 인수)를 사용하여, 그런 일을 할 수있는 :

template <typename T> 
using Template = typename get_template<SomeType>::type<T>; 

로 :

다음
template <typename T> 
    struct get_template; 

template <template <class...> class Y, typename... Args> 
    struct get_template<Y<Args...>> { 
    template <typename... Others> 
    using type = Y<Others...>; 
    }; 

템플릿을 얻기 위해 @Yakk에 의해 주석에 언급 된 위의 경우에만 형식 인수가있는 서식 파일에 대해서만 작동합니다. 당신은, 유형 및 비 타입 인수의 특정 패턴 템플릿 전문 수 있습니다 예컨대 :

// Note: You need the first size_t to avoid ambiguity with the first specialization 
template <template <class, size_t, size_t...> class Y, typename A, size_t... Sizes> 
    struct get_template<Y<A, Sizes...>> { 
    template <class U, size_t... OSizes> 
    using type = Y<U, OSizes...>; 
    }; 

...하지만 당신은 임의의 템플릿을 전문으로 할 수 없습니다.


DEMO (Foostd::pair 포함) :

#include <type_traits> 
#include <map> 

struct Bar{}; 

template <typename T> 
struct Foo {}; 

using SomeType = Foo<Bar>; 

template <typename T> 
    struct get_template; 

template <template <class...> class Y, typename... Args> 
    struct get_template<Y<Args...>> { 
    template <typename... Others> 
    using type = Y<Others...>; 
    }; 

template <typename T> 
using Template = typename get_template<SomeType>::type<T>; 

static_assert(std::is_same<SomeType, Template<Bar>>::value, ""); 
static_assert(std::is_same<Foo<int>, Template<int>>::value, ""); 

using PairIntInt = std::pair<int, int>; 
using PairIntDouble = std::pair<int, double>; 

template <typename U1, typename U2> 
using HopeItIsPair = 
    typename get_template<PairIntDouble>::type<U1, U2>; 

static_assert(std::is_same<PairIntDouble, HopeItIsPair<int, double>>::value, ""); 
static_assert(std::is_same<PairIntInt, HopeItIsPair<int, int>>::value, ""); 
+0

당연히 이는 유형을 취하는 템플릿 또는 유한 템플릿 패턴에서만 작동합니다. – Yakk

+0

@Yakk 예 ... 어떤 유형의 템플릿에서도 작동하도록하는 방법이 없다고 생각합니다 (특히 유형 및 비 유형 매개 변수를 인터리빙하는 경우). 그럼에도 불구하고 템플릿 인수 패턴에 대한 정보가 있으면 필요에 맞게 위의 코드를 쉽게 적용 할 수 있습니다. – Holt

1

확실하지 나는 질문이 있어요. 이게 효과가 있니? 당신은 훨씬 더 일반화 할 수

#include<type_traits> 
#include<utility> 

template<typename V, template<typename> class T, typename U> 
auto get_template(T<U>) { return T<V>{}; } 

struct Baz{}; 
struct Bar{}; 

template <typename T> 
struct Foo {}; 

using SomeType = Foo<Bar>; 

template <typename T> 
using Template = decltype(get_template<T>(SomeType{})); 

int main() { 
    static_assert(std::is_same<Foo<Baz>, Template<Baz>>::value, ""); 
} 

은 (SomeType 예로 들어 Template의 템플릿 매개 변수가 될 수있다),하지만 방법이 무엇인지에 대한 아이디어를 제공합니다.