2011-10-04 22 views
5

Dire che ho questo:modello di specializzazione con il modello più parametri

template<typename T, int X> 
class foo 
{ 
public: 
    void set(const T &t); 
}; 

template<typename T, int X> 
void foo::set<T, X>(const T &t) 
{ 
    int s = X; 
    // ...etc 
} 

Potrei specializzare il tipo di funzione 'T', ma lasciare 'X' come un parametro di modello?

class bar; 

template<int X> 
void foo::set<bar, X>(const bar &t) 
{ 
    int s = X; 
    // ...etc 
} 

È possibile?

+1

'void foo :: set (const T & t)' -> 'void foo :: set (const T & t)' –

risposta

6

Questo è sorprendentemente facile una volta a ottenere il blocco di esso

template<typename T, int X> 
class foo 
{ 
private: 
    template<typename, int> class params { }; 

public: 
    void set(const T &t) { 
    set(t, params<T, X>()); 
    } 

private: 
    template<typename T1, int X1> 
    void set(const T1 &t, params<T1, X1>) { 
    // ... 
    } 

    template<int X1> 
    void set(const bar &t, params<bar, X1>) { 
    // ... 
    } 
}; 

Ciò è necessario perché se siete specializzati in modo esplicito un singolo membro, è necessario fornire tutti gli argomenti di template . Non puoi lasciare un po '.

+0

Questo è corretto ma personalmente eviterei tali trucchi. Rende il codice illeggibile. La specializzazione parziale IMO della classe o qualcosa di simile a seconda della situazione (ad es. Creare template di classi base e specializzarlo parzialmente e implementare (molte?) Funzioni non specializzate in classi derivate non specializzate) è una decisione molto migliore. –

+0

La specializzazione parziale @Serge è specializzata nell'intera classe. Quindi non è adatto se vuole solo un comportamento speciale per una singola funzione. creare un modello base è molto più rumore e inconveniente (non avrai accesso ai membri di "foo", ...). Se hai una soluzione più pulita per quanto sopra, ti do il benvenuto per pubblicarlo. –

+0

"La specializzazione parziale è specializzata nell'intera classe" - Vero. "creare un modello di base è molto più rumore e inconveniente" - Di solito non è un inconveniente - è un lavoro aggiuntivo secondario per rendere l'architettura coerente. Se c'è bisogno di specializzazione, di solito c'è qualche logica speciale su questo caso che potrebbe meritare una specializzazione di classe separata (base). Se ci sono molti oggetti membri comuni, nessun problema è metterli (protetti) in un'altra classe per essere la base per entrambe le specializzazioni genitore (e di solito c'è una logica dietro questa). –

2

No. Ciò non è consentito. Una funzione membro classdeve essere completamente specializzata. Per esempio, dovrebbe essere,

template<> 
void foo<bar, 5>::set(const bar &t) 
{   //^^^^ 
    int s = 5; 
    // ...etc 
} 
1

È possibile specializzare parzialmente l'intera classe. In questo caso puoi dare diverse implementazioni alla funzione set per ogni specializzazione della classe.

+0

Puoi fare un esempio? – MarkP

+0

@MarkP, selezionare [this] (http://stackoverflow.com/questions/1535816/c-partition-method-specialization/1535845#1535845) risposta. –

3

si potrebbe considerare riscrivere il codice per rendere la funzione di membro di un modello a parte:

template <int X> class foo 
{ 
    template <typename T> void set(const T &); 
    // ... 
}; 

Quindi è possibile fornire specializzazioni esplicite per il modello foo<X>::set.

Problemi correlati