2012-11-15 20 views
7

Wie soll ich eine statische Variable für eine Teilspezialisierung initialisieren?C++ Wie statische Variablen einer partiellen Template-Spezialisierung initialisiert werden

template <bool A=true, bool B=false> 
struct from { 
    const static std::string value; 
}; 

// no specialization - works 
template <bool A, bool B> 
const std::string from<A, B>::value = ""; 

// partial specialization - does not compile - 
// Error: template argument list following class template name must list parameters in the order used in template parameter list 
// Error: from<A,B>' : too few template arguments 
template <bool B> 
const std::string from<true, B>::value = ""; 

// full specialization - works 
const std::string from<false, true>::value = ""; 

Warum funktioniert die Teilarbeit nicht?

EDIT: Ich habe eine Lösung gefunden, basierend auf Partial template specialization for initialization of static data members of template classes

ich die Erklärung für die partielle Spezialisierung wiederholen müssen, bevor sie mir die statische Variable zu initialisieren erlaubt:

template <bool B> 
struct from<true, B> { 
    const static std::string value; 
}; 

Auch hier ist die Frage, warum ?

+0

Welcher Compiler? Auf [g ++ 4.3.4] (http://ideone.com/jM6sIb) funktioniert auch die letzte nicht. – didierc

+0

Müssen Sie nicht auch die gesamte Klassenvorlage spezialisieren? Ich denke, dass nur explizite (= vollständige) Spezialisierung für Mitglieder erlaubt ist. –

+0

Compiler war VS2010 –

Antwort

3

Partielle Spezialisierung von Mitgliedern (unabhängig davon, ob es sich um Funktionen oder statische Daten handelt) sind ohne teilweise Spezialisierung der einschließenden Klassenvorlage selbst nicht zulässig.

Das heißt, Sie müssen auch die Klassenvorlage spezialisieren. So sollten folgende Arbeiten:

//partial specialization of class template 
template <bool B> 
struct from<true, B> { 
    const static std::string value; 
}; 

//now you can do this!  
template <bool B> 
const std::string from<true, B>::value = "" 

Auch dies wird nicht kompiliert (haben Sie versucht, diese Zusammenstellung?):

// full specialization - works (SORRY, IT WILL NOT WORK!) 
const std::string from<false, true>::value = ""; //this should be an error 

Sie haben, dies zu schreiben:

// full specialization 
template<> //<---- this is important! 
const std::string from<false, true>::value = "" 
+0

Ok. Mein Ziel ist es, einige if-the-else-Anweisungen durch die Templates zu ersetzen. Ich sehe, dass die Verwendung von statischen Variablen in diesem speziellen Szenario problematisch ist. Würden Sie einen Weg empfehlen, dieses Problem zu beheben? Ich möchte eine Zeichenfolge basierend auf den Vorlagenparameterwerten auswählen. –

+0

Sie schlagen mich dazu. – didierc

+0

@CandyChiu: Warum nicht stattdessen Array/Karte von String verwenden? Oder Sie könnten die Elementfunktion in einer Klassenvorlage verwenden, die einen anderen Wert basierend auf dem Wert der Vorlagenargumente zurückgibt. – Nawaz

2

Hier eine funktionierende vollständige Spezialisierung der Vorlage.

#include <string> 
#include <iostream> 

template <bool A=true, bool B=false> 
struct from { 
    const static std::string value; 
}; 

// no specialization - works 
template <bool A, bool B> 
const std::string from<A, B>::value = "no specialization"; 

// full specialization, note the empty template parameter list 
template <> 
const std::string from<true, true>::value = "<true,true> specialization"; 


int main() { 
    std::cout << from<false, false>::value << std::endl; 
    std::cout << from<true, true>::value << std::endl; 
} 

Sie haben die richtige Methode zur Definition der Partiellen gefunden.

Der Grund dafür, dass Ihr Teil nicht funktioniert, ist, dass Sie den Strukturtyp deklarieren müssen, bevor Sie eine Initialisierung für sein statisches Feld bereitstellen können. Die Teilspezialisierung ist eine eigene Vorlage und verdient eine Definition.

Die vollständige Spezialisierung ist eigentlich eine Typinstanz der ursprünglichen Vorlage und muss daher nicht separat definiert werden.

Verwandte Themen