2012-04-06 6 views
2

Ich habe ein Problem mit verschachtelten Vorlagen und ihre Vorlage Spezialisierung. Angesichts der folgenden Klassen:spezialisieren Vorlage <Typname T, Vorlage <typename> Klasse U>

Eine kleine Template-Klasse

template<class U> 
class T { 
public: 
    T(){} 
    virtual ~T(){} 

}; 

Und eine Art von verschachtelten Vorlage

template<typename T, template<typename> class U> 
class A { 
public: 
    void foo() 
    { 
     std::cerr << "A generic foo"; 
    } 
}; 

Und eine kleine main.cpp

int main(int argc, const char *argv[]) 
{ 
    A<int,T> *a = new A<int,T>; 
    a->foo(); 

    //This wont work: 
    A<double,T*> *b = new A<double,T*>; 
    b->foo(); 

    return 0; 
} 

Jetzt brauche ich ein Spezialisierung, wenn U ein Zeiger ist:

A<double,T*> *b = new A<double,T*>; 
    b->foo(); 

Wie erreichen? Ich habe versucht, so etwas wie:

template<typename T, template<typename> class U> 
class A< T, U* > 
{ 
public: 
void foo() 
{ 
    std::cerr << "A specialized foo"; 
} 
}; 

Aber es löst nur in

A.h:18:16: Error: Templateargument 2 is invalid 
+0

Sie scheinen verwirrt zu sein. –

+0

@ildjarn: Nein, das ist in Ordnung, weil 'A' etwas erwartet, das ein Schablonentyp mit einem Parameter ist. 'T' passt zu dieser Rechnung. – bitmask

+0

@bitmask: Ah, völlig richtig, ich habe anscheinend nicht aufgepasst. – ildjarn

Antwort

0

Was Sie binden nicht möglich zu tun ist, weil T* keine Bedeutung hat. Es ist weder ein richtiger Typ, noch entspricht es einer Vorlage, die zusätzliche Parameter erfordert. Wenn UT* darstellen würde, was wäre U<int>? Sie meinen wahrscheinlich T<int>*, aber das stimmt nicht mit Ihrer Deklaration überein, daher gibt es keine Möglichkeit, diesen Typ in A zu stecken.

Da Sie nach einer Möglichkeit gefragt haben, um dies zu umgehen, von der Spitze meines Kopfes, etwa so.

Accept ein drittes Template-Argument zu A, die ich Expander nennen würde und setzen Sie ihn standardmäßig dies:

template <typename T> struct Expander { 
    typedef T type; 
}; 

Wenn dann A Aufruf Sie

A<int,T> normal; 
A<int,T,PtrExpander> pointer; 

mit

sagen konnte
template <typename T> struct PtrExpander { 
    typedef T* type; 
}; 

und A wäre:

template<typename T, template<typename> class U, template <typename> class E = Expander> class A { 
    typedef typename E<U<Your_Args_to_U> >::type; 
+0

Aber T stellt eine Vorlage dar, nicht wahr? – user988017

+0

@ user988017: Ja, aber 'T *' nicht. Da 'T' kein Typ ist (es ist eine Vorlage), können Sie keinen Zeiger darauf haben. C++ * könnte Ihnen diese informelle Notation erlauben, tut es aber nicht. – bitmask

+0

Ich sehe ... was ist der einfachste Weg, um dies zu umgehen? – user988017

Verwandte Themen