2012-04-04 5 views
5

Dato un modellomodello Specializzarsi sulla base di positività di argomentazione

template <int n> 
void f(){...}; 

So che posso specializzare per valori specifici di n facendo:

template <> 
void f<2>(){...}; 

Ma, c'è un metodo che mi permette specializzarlo per tutto il positivo n?

ho pensato di fare la seguente

template <int n> 
void f<n>(){ 
    int dummy[n]; //invalid for n < 0 
    ... 
}; 

Così per n<0 questo codice non è valido e il compilatore dovrebbe ricorrere alla definizione precedente. Sfortunatamente, tutto ciò che ottengo è un errore redefinition of 'void f<n>()'.

Nota: immagino che probabilmente non è supportato dallo standard. Sto chiedendo se non c'è qualche metodo (forse qualche metaprogramma del modello) per ottenere questo effetto.

risposta

13

Un'opzione sarebbe quella di utilizzare un altro livello di riferimento indiretto. Definire un modello ausiliario che includa due argomenti: il numero n e un bool che rappresentino o meno n negativo, quindi specializzare quel modello per quando n è negativo. Quindi, la tua funzione f crea un'istanza del modello con gli argomenti giusti.

Ad esempio:

template <int n, bool isNegative> struct fImpl { 
    static void f() { 
     /* ... code for when n is positive ... */ 
    } 
}; 
template <int n> struct fImpl<n, true> { 
    static void f() { 
     /* ... code for when n is negative ... */ 
    } 
}; 

template <int n> void f() { 
    fImpl<n, (n < 0)>::f(); 
} 

Un'altra opzione è quella di utilizzare SFINAE overloading e la classe std::enable_if modello da C++ 11 (o equivalente del Boost);

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) { 
    /* ... n is negative ... */ 
} 

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) { 
    /* ... n is positive ... */ 
} 

Ciascuna di queste funzioni saranno disponibili per la risoluzione di sovraccarico solo se n ha il segno corretto, quindi la versione corretta sarà sempre chiamato.

Spero che questo aiuti!

+5

Questione di stile, ma preferisco inserire 'enable_if' nel tipo restituito, quindi non c'è un parametro magico che gira attorno a cose confuse (gli utenti e il tipo di funzione). – GManNickG

Problemi correlati