2012-11-15 16 views
7

Come inizializzare una variabile statica per una specializzazione parziale?C++ Come inizializzare le variabili statiche di una specializzazione di modello parziale

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 = ""; 

Perché il lavoro parziale non funziona?

EDIT: ho trovato una soluzione basata su Partial template specialization for initialization of static data members of template classes

ho bisogno di ripetere la dichiarazione per la specializzazione parziale prima mi ha permesso di inizializzare la variabile statica:

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

Anche in questo caso, la domanda è perché ?

+0

Quale compilatore? Su [g ++ 4.3.4] (http://ideone.com/jM6sIb), anche l'ultimo non funziona. – didierc

+0

Non devi specializzare anche l'intero modello di classe? Penso che solo la specializzazione esplicita (= completa) sia consentita per i membri. Il compilatore –

+0

era VS2010 –

risposta

3

La specializzazione parziale dei membri (che si tratti di funzioni o dati statici) non è consentita senza una specializzazione parziale del modello di classe che lo racchiude.

Cioè, devi anche specializzare il modello di classe. Così il seguente dovrebbe funzionare:

//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 = "" 

Inoltre, questa non verrà compilato (hai provato la compilazione di questo?):

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

Hai per scrivere questo:

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

Ok. Il mio obiettivo è sostituire qualche istruzione if-the-else dai template. Vedo che l'uso di variabili statiche in questo particolare scenario è problematico. Consiglieresti un modo per risolvere questo problema? Mi piacerebbe selezionare una stringa in base ai valori dei parametri del modello. –

+0

mi hai battuto su di esso. – didierc

+0

@CandyChiu: Perché non usare array/mappa di stringa, invece? Oppure è possibile utilizzare la funzione membro in un modello di classe che restituirà valori diversi in base al valore degli argomenti del modello. – Nawaz

2

Ecco una piena specializzazione di lavoro del modello.

#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; 
} 

Hai trovato il modo corretto di definire il parziale.

Il motivo per cui il vostro parziale non funziona è che è necessario dichiarare il tipo di struttura prima di poter fornire un'inizializzazione per il suo campo statico. La specializzazione parziale è un modello a sé stante e merita una definizione.

La specializzazione completa è in realtà un'istanza di tipo del modello iniziale e, pertanto, non è necessario definirla separatamente.

Problemi correlati