2015-03-30 7 views
7

Mam cechę typu, który sprawdza, czy dany typ jest wystąpienie danego szablonu klasy:ujednolicić rodzaj i non-type parametry szablonu

template <template <typename...> class C, typename T> 
struct check_is_instance_of : std::false_type { }; 

template <template <typename...> class C, typename ...Ts> 
struct check_is_instance_of<C, C<Ts...>> : std::true_type { }; 

template <template <typename...> class C, typename T> 
struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { }; 

Niestety, to nie działa dla parametrów szablonu dla typu ponieważ nie są "przechwytywane" przez parametry szablonu wariadycznego, więc daje błąd kompilacji. Czy istnieje sposób na napisanie implementacji is_instance_of, która działa dla dowolnej liczby parametrów typu i typu szablonu?

+0

Nie jest to odpowiedź na twoje pytanie, ale ta implementacja nie zadziała z aliasami szablonu szablonu. Może tego właśnie chcesz, ale może nie. – TartanLlama

Odpowiedz

1

Nie sądzę, jest to czysty sposób to zrobić chyba że wszystkie argumenty typu są tego samego typu i wiesz, jaki to jest typ. W tym szczególnym przypadku można użyć przeciążenia funkcji.

W każdym innym przypadku kończy się to na szablonowej wersji idealnego problemu z przekazywaniem, w którym trzeba by specjalizować się w każdej kombinacji argumentów typu/nontype.

Jeśli potrzebujesz tylko adresować homogeniczne argumenty inne niż szablonowe i możesz odgadnąć typ, poniższe elementy powinny działać. Można przeciążać instance_of dla różnych typów (tylko int pokryta jest tutaj), ale trzeba jawnie utworzyć instancję dla każdego rodzaju chcesz być w stanie obsługiwać:

// variation for non-type parameters, only for uniform parameters with 
// known type. 
template <typename V, template <V...> class C, typename T> 
struct check_is_instance_of_nontype : std::false_type { }; 

template <typename V, template <V...> class C, V... Values> 
struct check_is_instance_of_nontype<V, C, C<Values...>> : std::true_type { }; 

// this is as in your example 
template <template <typename...> class C, typename T> 
struct check_is_instance_of : std::false_type { }; 

template <template <typename...> class C, typename ...Ts> 
struct check_is_instance_of<C, C<Ts...>> : std::true_type { }; 

template <template <typename...> class C, typename T> 
struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { }; 

template <template <typename...> class C, typename T> 
constexpr bool instance_of() 
{ 
    return is_instance_of< C, T>::value; 
} 

template <template <int...> class C, typename T> 
constexpr bool instance_of() 
{ 
    return check_is_instance_of_nontype< int, C, T>::value; 
} 

template<int...> 
struct Duck 
{ 
}; 

template<typename A, typename B> 
struct Swallow 
{ 

}; 

int main() { 
    typedef Duck<1, 2> SittingDuck; 
    typedef Swallow< int, int> UnladenSwallow; 

    std::cout << instance_of< Duck, SittingDuck>() << instance_of< Swallow, UnladenSwallow>(); 
    return 0; 
}