2012-10-02 15 views
9

Ich versuche, etwas Teilspezialisierung zu machen. Ich habe eine tuple, und ich möchte von einem bestimmten Elementindex auf den ersten Tupelindex iterieren und einen Wert von jedem Typ in der tuple akkumulieren. Dies scheint eine einfache Sache zu sein, eine rekursive Template-Instanziierung zu verwenden.Partielle Spezialisierung von Templates mit ganzzahligen Parametern

Das Problem ist, ich kann nicht scheinen, die Rekursion zu arbeiten. Um die Rekursion zu stoppen, muss ich die Template-Funktion bei Tupel-Index 0 teilweise spezialisieren. Das schien einfach genug, aber es funktioniert nicht.

Hinweis: Ich habe die tatsächlichen tuple Sachen aus dem Beispiel entfernt, da es irrelevant ist; Es ist die Template-Spezialisierung, die nicht funktioniert.

template<int Index, typename Tpl> 
size_t CalcInterleaveByteOffset(const Tpl &t) 
{ 
    size_t prevOffset = CalcInterleaveByteOffset<Index - 1>(t); 
    return prevOffset + sizeof(Tpl); 
} 

template<typename Tpl> 
size_t CalcInterleaveByteOffset<0, Tpl>(const Tpl &t) 
{ 
    return 0; 
} 

GCC simply says that this kind of specialization is not allowed. Ist das wahr? Gibt es einen anderen Weg, mit so etwas umzugehen?

Antwort

11

In der Regel ist jede Form der partiellen Template-Spezialisierung für Funktionen nicht erlaubt. Es ist jedoch für Klassen erlaubt. Die Lösung besteht also einfach darin, Ihre Funktion in ein statisches Mitglied einer Vorlagenhalterklasse zu verschieben.

Wenn Sie die Vorlagenargumente ableiten müssen, können Sie einfach eine Wrapperfunktion erstellen, die die Vorlagenklasse aufruft.

Das Ergebnis ist so etwas wie dieses:

template<int Index, typename Tpl> 
class CalcInterleaveByteOffsetImpl 
{ 
    static size_t CalcInterleaveByteOffset(const Tpl &t) 
    { 
    // This is OK it calls the wrapper function 
    // You could also do 
    // size_t prevOffset = CalcInterleaveByteOffsetImpl<Index - 1, Tpl>::CalcInterleaveByteOffset(t); 
    size_t prevOffset = ::CalcInterleaveByteOffset<Index - 1>(t); 
    return prevOffset + sizeof(Tpl); 
    } 
}; 

template<typename Tpl> 
class CalcInterleaveByteOffsetImpl<0, Tpl> 
{ 
    static size_t CalcInterleaveByteOffset(const Tpl &t) 
    { 
    return 0; 
    } 
}; 

template<int Index, typename Tpl> 
size_t CalcInterleaveByteOffset(const Tpl &t) 
{ 
    return CalcInterlaveByteOffsetImpl<Index,Tpl>::CalcInterleaveByteOffset(t); 
} 
+0

konnte ich andere Klasse mit verschiedenen Mitgliedern Variablen unterscheiden diese Art und Weise? Ich könnte ja erraten? – GameDeveloper

Verwandte Themen