2017-07-25 2 views
4

Angenommen std::vector hatte keine value_type. Ist es möglich, eine Vorlage zu schreiben, um die value_type abzuleiten? Oder allgemeiner ausgedrückt, wie kann ich unter der T<X>X ableiten?Wie bekomme ich den Template-Parameter eines Template-Template-Parameters?

Ein sehr naiv ..

template <template <typename X> T> 
void test(T<X> t) { 
    X x; 
} 

wird wahrscheinlich jemand machen, der ein wenig weiß über Vorlagen an meinem törichten Versuch, lachen und wenn wie folgt instanziiert:

int main() { 
    std::vector<int> x; 
    test(x); 
} 

erstellen die folgenden Fehler:

error: expected ‘class’ before ‘T’ 
template < template<typename X> T> 
           ^
error: ‘X’ was not declared in this scope 
void test(T<X> u) { 
      ^
error: template argument 1 is invalid 
void test(T<X> u) { 
      ^
In function ‘void test(int)’: 
error: ‘X’ was not declared in this scope 
    X x; 
^
error: expected ‘;’ before ‘x’ 
    X x; 
    ^
In function ‘int main()’: 
error: no matching function for call to ‘test(std::vector<int>&)’ 
    test(x); 
     ^
note: candidate is: 
note: template<template<class X> class T> void test(int) 
void test(T<X> u) { 
    ^
note: template argument deduction/substitution failed: 
note: cannot convert ‘x’ (type ‘std::vector<int>’) to type ‘int’ 

EDIT: der erste ist einfach zu beheben, aber die Befestigung wird nicht beeinflussen die o thers ...

PS: Ich denke, ich habe ein kleines Missverständnis, als std::vector<int> ist nicht eine Vorlage, sondern ein konkreter Typ. Trotzdem würde ich gerne wissen, ob es einen Weg gibt, die int von einem someTemplate<int> mit etwas Vorlagenmagie zu bekommen.

+0

Wenn ich richtig erinnere, Sie müssen 'class' mit verschachtelten Vorlagen verwenden. Etwas wie 'Vorlage Klasse T>'. – pingul

+1

Beachten Sie, dass 'std :: vector' einen zweiten (voreingestellten) Template-Parameter hat. – Jarod42

+0

Art der Arbeit, aber wenn Sie nur mit Containern arbeiten, können Sie einen Iterator dazu bekommen und 'std :: iterator_traits' verwenden. – NathanOliver

Antwort

5

Sie eine Züge erstellen können diese Parameter zu extrahieren:

template <typename T> struct first_param; 

template <template <typename, typename...> class C, typename T, typename ...Ts> 
struct first_param<C<T, Ts...>> 
{ 
    using type = T; 
}; 

Für 11 pre C++, Sie haben bis akzeptable Werte Anzahl von Parametern zu handhaben:

template <typename T> struct first_param; 

template <template <typename> class C, typename T> 
struct first_param<C<T>> 
{ 
    typedef T type; 
}; 

template <template <typename, typename> class C, typename T, typename T2> 
struct first_param<C<T, T2>> 
{ 
    typedef T type; 
}; 

template <template <typename, typename, typename> class C, 
      typename T, typename T2, typename T3> 
struct first_param<C<T, T2, T3>> 
{ 
    typedef T type; 
}; 

// ... 
+0

sieht aus wie C++ 11 oder höher, sorry, wenn ich nicht explizit in der Frage war. – user463035818

+0

@ tobi303: C++ 03-Version hinzugefügt. – Jarod42

+0

Ich habe Glück und der konkrete Fall, nach dem ich suche, hat nur einen Parameter. Danke für die Antwort. Als ich all diese "..." und "using" sah, fürchtete ich, dass die C++ 03-Lösung ein schrecklicher Hack sein wird, aber diese Lösung sieht ziemlich gut und einfach aus – user463035818

Verwandte Themen