2012-04-02 4 views
4

Ich habe eine Template-Klasse mit einer variadic Template Member-Funktion, die ich nicht von außerhalb der Klasse aufrufen kann. Dies ist ein vereinfachtes Beispiel dafür, was ich versuche zu tun:Variadische Argumentfunktion aus Template-Klasse aufrufen

template<typename T> 
struct foo{ 
    foo(){} 

    template<int... I> 
    int run(){ 
     return sizeof...(I); // or whatever 
    } 
}; 

template<int... I> 
int run_int(){ 
    return foo<int>().run<I...>(); // OK 
} 

template<typename T, int... I> 
int run_T(){ 
    return foo<T>().run<I...>(); // error 
} 

Wenn foo spezialisiert ist, kann ich seine Vorlage Memberfunktion Lauf() aufrufen, ohne Probleme. Aber wenn ich versuche, es von einer Funktion oder Struktur aufzurufen, die nicht auf foo spezialisiert ist, gibt gcc (4.7) einen Fehler aus, der besagt, dass "Parameterpakete nicht mit '...' erweitert wurden". Ich habe das gleiche mit clang (3.1) versucht, habe aber einen ähnlichen Fehler ("error: Ausdruck enthält nicht expandiertes Parameterpaket 'I'").

Kann mir jemand helfen zu verstehen, warum die letzte Funktion nicht kompilieren kann? Denn jetzt kann ich es umgehen, indem sie „int ... I“ ein Nicht-Typ-Parameter von foo selbst, und es dann so nennen von außen:

foo<T, I...>().run() 

aber ich bin immer noch verwirrt, warum es kompiliert nicht anders herum.

+8

'foo () .template Lauf ()' –

+1

@LucDanton: Sie sollten das als die Antwort posten. Hier ist ein Zitat der Regel: 'Wenn der Name einer Mitgliedervorlagenspezialisierung danach erscheint. oder -> in einem Postfix-Ausdruck oder nach einem verschachtelten Namen-Spezifizierer in einer qualifizierten ID, und der Objekt- oder Zeigerausdruck des Postfix-Ausdrucks oder der Verschachtelungsname-Spezifizierer in der qualifizierten ID hängt von a ab Template-Parameter (14.6.2), aber bezieht sich nicht auf ein Mitglied der aktuellen Instanziierung (14.6.2.1), der Name der Member-Vorlage muss das Schlüsselwort Templates vorangestellt werden.' –

Antwort

6

rep sammeln gehen ...

foo<T>().template run<I...>(); 

Siehe Where and why do I have to put the "template" and "typename" keywords?, warum die Vorlage Schlüsselwort benötigt wird.

+0

Aha! Es ist die Fehlermeldung, die mich abwarf. Wenn Sie dies mit einer verschachtelten Struktur tun, wird gcc Ihnen sagen "Template" sagen, aber in diesem Fall hat mich die Fehlermeldung verwirrt. Vielen Dank für die Antwort und den Link - Sie sind eine große Hilfe! – ds1848