1

Ich habe diese Funktion, die rekursiv arbeiten sollte.Partielle Spezialisierung einer variablen Vorlage Funktion

template <class C, typename ...Arguments> 
void addStyleClassRecursive(C *c, Arguments... arg) 
{   
    c->addStyleClass(arg...); 
    for (unsigned int i=0; i<c->children().size(); ++i) 
    { 
     addStyleClassRecursive(c->children()[i], arg...); 
    }  
} 

Nun kommt es vor, dass ich irgendwann eine Klasse getroffen (Wt::WObject), die nicht die addStyleClass Memberfunktion hat, so dass der Compiler beschwert sich über dieses Problem -rightly-. Ok. Also dachte ich, den Code zu spezialisieren, und fügte hinzu, eine Version für Wt::WObject:

template <class C=Wt::WObject, typename ...Arguments> 
void addStyleClassRecursive(Wt::WObject *c, Arguments... arg) 
{ 
    for (unsigned int i=0; i<c->children().size(); ++i) 
    { 
     addStyleClassRecursive(c->children()[i], arg...); 
    } 
} 

Dies ist kein Compiler-Fehler in sich selbst nicht geben, aber es ist völlig ignoriert (in der Tat der Compiler beschwert hält über WObject nicht die erforderliche Element Funktion, die auf die gleiche Zeile innerhalb der allgemeinen Funktion zeigt).

Also versuchte ich es auf diese Weise

template <typename ...Arguments> 
void addStyleClassRecursive<Wt::WObject, Arguments...>(Wt::WObject *c, Arguments... arg) 
{ 
    for (unsigned int i=0; i<c->children().size(); ++i) 
    { 
     addStyleClassRecursive(c->children()[i], arg...); 
    } 
} 

Jetzt ist der Compiler beschwert sich über können

non-type partial specialization 'addStyleClassRecursive<Wt::WObject, Arguments ...>' is not allowed 
void addStyleClassRecursive<Wt::WObject, Arguments...>(Wt::WObject *c, Arguments... arg); 
                         ^

So zu spezialisieren jemand darauf hinweisen, wie das gewünschte Ergebnis zu erreichen?

Antwort

2

Sie können etwas tun:

template <class C, typename ...Arguments> 
auto addStyleClassRecursiveImpl(int, C *c, Arguments... arg) 
-> decltype(c->addStyleClass(arg...), void()) { 
    c->addStyleClass(arg...); 
    // ... C has addStyleClass 
} 

template <class C, typename ...Arguments> 
void addStyleClassRecursiveImpl(char, C *c, Arguments... arg) { 
    // ... C has not addStyleClass 
} 

template <typename... T> 
void addStyleClassRecursive(T ...&&t) { 
    addStyleClassRecursiveImpl(0, std::forward<T>(t)...); 
    // ... 
} 

Die Idee ist, -Tag-Versand die Anforderung an eine interne Implementierung (addStyleClassRecursiveImpl im Beispiel genannt) und verwenden sfinae und Funktion Überlastung holen die richtige Version.


Und natürlich können Sie eine Funktionsvorlage nicht teilweise spezialisieren.

+0

Ich musste einige kleine Änderungen vornehmen, damit es funktionierte, aber praktisch war dies eine Plug-and-Play-Lösung. Vielen Dank. – DrHell

+1

@DrHell Ich habe es von einem Mobiltelefon aus geschrieben, also bitte vergib mir, wenn es Tippfehler gibt. Ich bin froh, dass es für dich funktioniert. – skypjack

+1

Sorry, ich wollte nicht arrogant klingen oder was auch immer, ich erklärte, dass es ein paar kleine Änderungen brauchte, nur für den Fall, dass jemand es in Zukunft benutzen wollte und fragte sich, warum es beim ersten Versuch nicht funktionierte. Danke noch einmal. :) – DrHell

2

Sie können eine Funktionsvorlage nicht teilweise spezialisieren.

Was Sie tun können, ist die rekursive Vorlage eine andere Funktion auf ihre erste variadic Vorlage arg aufrufen, und dann rekursiv selbst auf den Rest der Argumente aufrufen. Dann können Sie die Hilfsfunktion vollständig spezialisieren.

Verwandte Themen