2012-07-23 16 views
5

Ho il seguente codice:Utilizzando Specializzazione parziale in C++ 11

template<class T, int I=44> struct test {T j = I;}; 

template<int J> struct test<int, J> {int j = J;}; 

int main() 
{ 
    test<55> jj; 

    std::cout << jj.j << std::endl; 
    return(1); 
} 

Il compilatore (clang) si lamenta solo la linea test<55> jj

Non capisco perché? C'è un lavoro in giro?

E se si lamenta di quella riga, perché non si lamenta della seconda definizione del modello?

Grazie in anticipo.

Il messaggio è:

enable.cpp:17:8: error: template argument for template type parameter must be a type 
test<55> jj; 
    ^~ 
enable.cpp:9:16: note: template parameter is declared here 
template<class T, int I=44> struct test 
+0

Potresti collegare il messaggio di errore? – Morwenn

risposta

6

Il problema è che non hai capito come funziona la specializzazione del modello di classe.

tua specializzazione:

template<int J> struct test<int, J> {int j = J;}; 

non crea un modello per il quale si dispone solo di passare in un unico parametro di modello int.

test<55> jj; // doesn't work because there's no template<int J> struct test 

Invece ciò che fa è creare una specializzazione di template<class T, int I> struct test che sarà utilizzato quando gli argomenti di template per template<class T, int I> struct test corrispondono alla specializzazione, vale a dire test<int,J>.

test<int,55> jj; // uses the specialization template<int J> struct test<int, J> 

Ecco la citazione chiave dalla norma:

In un nome di tipo che si riferisce ad una specializzazione modello di classe, (ad esempio, A<int, int, 1>) la lista degli argomenti deve corrispondere al parametro di template elenco di il modello principale. Gli argomenti del modello di una specializzazione vengono dedotti dagli argomenti del modello principale.[enfasi aggiunta]

                                                                                                                                                                      - 14.5.5.1 [temp.class.spec.match] p4


Sembra che tu stia tentando di impostare int come un tipo predefinito per T mentre contemporaneamente si imposta un indipendente valore predefinito per I. Penso che il tuo intento sia di essere in grado di specificare un tipo e un valore, specificare solo un tipo e ottenere 44 come valore predefinito, o specificare solo un valore e ottenere int come un tipo predefinito.

Purtroppo non conosco un modo per specificare valori predefiniti indipendenti come quello. È possibile specificare i valori predefiniti (template<class T=int, int I=44> struct test) ma per ottenere il tipo predefinito sarà necessario accettare anche il valore predefinito.

Tuttavia, se siete disposti a utilizzare un secondo nome allora si può fare:

template <int I> 
using test_int = test<int, I>; 

Questo crea un modello alias tali che basta specificare un valore:

test_int<55> jj; 

E questo finirà per usare qualunque specializzazione test<int, I> capita di stabilire se c'è una specializzazione esplicita o il compilatore ne genera uno implicito.

3

Il primo errore si verifica perché il compilatore tenta di creare un'istanza il parametro prima modello (class T) con 55. Questo non funziona, perché 55 non è un tipo di per sé, ma un'istanza di esso. Tuttavia, test<int> funziona perché qui il template template è un tipo, come richiesto dalla firma del modello.

Quello che vuoi invece è "currying" per i tipi, aka. modello di aliasing:

template <typename T> 
struct test2 = using test<T, 55>; 

Qui avete solo bisogno di fornire una T per scegliere 55 come secondo parametro fisso. Tuttavia, devi ancora utilizzare quel tipo dandogli un numero di telefono T, ad esempio test2<double>.

I commenti hanno indicato si potrebbe anche essere interessato al seguente variante:

template <int I> 
using test3 = test<int, I>; 

Qui fissare il primo parametro di tipo int, che permette di utilizzarlo come avete fatto nel codice:

test3<55> t; 
+0

Ci sono così tante cose sbagliate nel codice ... In primo luogo, la sintassi ovviamente fallisce. Secondo, non vuole specificare il tipo. Terzo, questa non è una specializzazione parziale. – Xeo

+3

La specializzazione corregge T a int, e usa 55 solo come valore che sta usando. Probabilmente stai cercando 'template usando test_int = test ;, invece. – bames53

+0

L'alias del modello nella risposta equivale a un valore predefinito, che non è quello che l'utente desidera realmente. –

Problemi correlati