2015-03-30 13 views
7

ich eine Art Charakterzug haben, die eine bestimmte Art überprüft, ob eine Instanz einer Klasse Vorlage:Unify Typ und nicht-Typ Template-Parameter

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>> { }; 

Leider funktioniert das nicht für Nicht-Typ Template-Parameter da sie nicht von den variadischen Vorlagenparametern "erfasst" werden, führt

is_instance_of<std::integral_constant, std::true_type> 

zu einem Kompilierfehler. Gibt es eine Möglichkeit eine Implementierung von is_instance_of, die für eine beliebige Anzahl von Typ und nicht-Typ Template-Parametern arbeitet zu schreiben?

+0

keine Antwort auf Ihre Frage, aber Diese Implementierung funktioniert nicht mit Vorlagenvorlagenaliasnamen. Vielleicht ist das was du willst, aber vielleicht nicht. – TartanLlama

Antwort

1

Ich glaube nicht, dass es eine saubere Möglichkeit gibt, dies zu tun , es sei denn die Nicht-Typ-Argumente sind alle vom gleichen Typ und Sie wissen, welcher Typ es ist. In diesem speziellen Fall kann das Überladen von Funktionen verwendet werden.

In jedem anderen Fall, erhalten Sie in einer Template-Argumente Version des perfekten Forwarding Problems, wo Sie für jede Art/untypischen Konstruktionen Argument Kombination spezialisiert haben würden.

Wenn Sie nur homogene Nicht-Template-Argumente müssen Adresse und der Typ erraten kann, sollte die folgende arbeiten. Sie können instance_of für verschiedene Arten überlasten (nur int hier abgedeckt wird), aber man müßte explizit eine Instanz für jede Sie zu handhaben können, wollen Typen erstellen:

// 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; 
}