Lllezione 12
Template
Template
Lezione 12
ü Il template è un meccanismo che consente di creare uno
schema generico di funzione o di classe, che non fa
esplicito riferimento a nessun particolare tipo di dati
®
utile quando si devono implementare più funzioni o classi che
si comportano allo stesso modo ma lavorano su dati di tipo
diverso
ü Il template consente di progettare solo uno schema
generale per implementare una particolare operazione
®
Il compilatore provvede a produrre da questo schema il codice
effettivo per implementare l’operazione su ogni tipo di dati
(predefinito o definito dall’utente)
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Cosa è un Template
1
Laboratorio di Algoritmi e Strutture Dati
2001/02
1
Lllezione 12
Template
ü Il template di funzione è uno schema di funzione
generica, che non fa esplicito riferimento a nessun
particolare tipo di dati input
®
consente di progettare un’unica funzione per implementare una
particolare operazione
ü All’interno del codice del programma di sarà una
diversa funzione per implementare l’operazione su ogni
tipo di dati
®
®
La generazione di tutte le funzioni è a carico del compilatore
Il compilatore provvede a produrre da questo schema una
diversa funzione per ogni tipo di dati
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Cosa è un Template di Funzione
2
ü Il template di classe è uno schema di classe generica, che
non fa esplicito riferimento a nessun particolare tipo di
dati membro
®
consente di progettare un’unica classe per implementare un
tipo di dato astratto, indipendente dal tipo di dato contenuto al
suo interno
ü All’interno del codice del programma ci sarà una
diversa classe per implementare il tipo di dato astratto
per ogni possibile tipo di dato membro
®
®
La generazione di tutte le classi e dei suoi metodi è a carico del
compilatore
Il compilatore provvede a produrre da questo schema una
diversa classe per ogni tipo di dato membro
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Cosa è un Template di Classe
3
Laboratorio di Algoritmi e Strutture Dati
2001/02
2
Lllezione 12
Template
ü L’overloading consente di assegnare lo stesso
nome a funzioni differenti
®
®
il programmatore deve scrivere tutte le funzioni
semplificazione esclusivamente lessicale (assegna un
nome ad ogni operazione logica)
ü Il template è uno schema di funzione che può
essere applicato su diversi dati
®
®
il programmatore deve scrivere una sola funzione
tutte le versioni ricavate dallo schema devono avere la
stessa implementazione e differire solo per il tipo dei
dato su cui operano
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Template e Overloading
4
ü Molti linguaggi di programmazione hanno meccanismi
che consentono di scrivere delle funzioni generiche
®
In C è possibile usare le macro per produrre funzioni generiche
#define max(a,b) ((a)>(b)) ? (a) : (b)
ü Le macro effettuano una sostituzione testuale degli
argomenti con i valori passati nella chiamata alla macro
® nessun controllo sui tipi
® il compilatore non è in grado di supportare il controllo sui tipi
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Schemi di Funzione in C
5
Laboratorio di Algoritmi e Strutture Dati
2001/02
3
Lllezione 12
Template
Quando Creare Template di
Funzioni
versioni della stessa funzione che lavorano su dati di
tipo diverso
®
Operano tutte alla stessa maniera ma usano variabili di tipo
diverso
int max(int, int);
// massimo tra due interi
char max(char, char);
// massimo in un vettore di interi
double max(double, double); // massimo tra due double
ü Si possono utilizzare i template di funzioni per creare
librerie di funzioni generiche
® l’utente della libreria potrà utilizzare la libreria su qualunque
tipo di dati
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Creare un template di funzioni se si devono usare più
6
Definizione di un Template
definito prima di essere utilizzato dal programma
ü La definizione (dichiarazione) di un template di
funzione è una definizione (dichiarazione) di una
funzione parametrizzata
template <class T>
T max( T* a, int dim) { \\ max in un array (di ogni tipo)
T tmp = a[0];
for( int i = 1; i < dim; i++ )
if( a[i] > tmp )
tmp = a[i];
return tmp;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Il template di una funzione deve essere dichiarato o
7
Laboratorio di Algoritmi e Strutture Dati
2001/02
4
Lllezione 12
Template
Parametri del Template
deve specificare la lista dei parametri, tra <>
®
Parametri rispetto ai quali è descritto il comportamento
della funzione
ü Un parametro può essere
®
un tipo (parametro di tipo)
w Preceduto dalle parole class o typename
®
un’espressione costante (parametro di valore)
w Preceduta dal tipo del risultato dell’espressione
template <class T, int size>
T max( T (&a)[size]) {
\\ max in un array di dimensione size di tipo T
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Nella definizione (dichiarazione) di un template si
8
ü La parola riservata template e la lista dei
parametri del template sono obbligatori
®
Ogni parametro deve essere preceduto dal suo tipo
w class (typename) tipo predefinito (definito dall’utente)
®
Tutti i parametri devono avere nomi distinti
®
Ogni parametro deve comparire nella firma della
funzione
®
Il nome del parametro non può essere ridefinito nella
funzione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Corretta Definizione di un
Template
9
Laboratorio di Algoritmi e Strutture Dati
2001/02
5
Lllezione 12
Template
template <class T, class T> T f(T, T);
// ERRORE
template <class T, U> void f(T, U);
// ERRORE
template <class T, typename U> void f(T, U); // CORRETTO
template <class T, class U> U f(T, T);
// ERRORE
template <class T> T f(T, T) { typedef double T; … }
// ERRORE
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempi Dichiarazioni di Template
10
ü Lo
standard
C++
supporta
l’inizializzaione per default dei parametri
di un template
Valgono le stesse regole per l’inizializzazione
per default dei parametri di una funzione
® Non tutti i compilatori supportano questa
proprietà
®
üI
compilatori
pre-standard
non
supportano l’inizializzazione per default
dei parametri del template
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Inizializzazione di Default dei
Parametri del Template
11
Laboratorio di Algoritmi e Strutture Dati
2001/02
6
Lllezione 12
Template
Istanziazione di un Template
template non alloca nessuna memoria
®
®
non è in grado di calcolare la dimensione del record di
attivazione
non sa come implementare la funzione parametrizzata
ü La definizione delle varie istanze di funzioni ricavate
dal template (istanziazione del template) avviene solo
quando queste funzioni vengono utilizzate
®
®
Funzione invocata dal programma
assegnamento dell’indirizzo della funzione ad un puntatore
ü l'istruzione che provoca l'istanziazione è detta punto di
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Quando il compilatore legge la definizione di un
istanziazione
12
Istanziazione di un Template
ricavate dal template il compilatore opera nel
seguente modo:
1.
2.
3.
4.
5.
sospende la compilazione,
recupera la definizione del template,
deduce dalla chiamata i tipi ed i valori dei parametri
sostituisce ai parametri del template i tipi ed i valori dedotti,
definisce la funzione così ottenuta
ü L’istanziazione avviene soltanto la prima volta che
una funzione viene invocata
®
le chiamate successive sono implementate normalmente
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Quando il programma invoca una delle funzioni
13
Laboratorio di Algoritmi e Strutture Dati
2001/02
7
Lllezione 12
Template
template <class T>
T max(T*, int);
int ai[4] = { 12, 8, 73, 45 };
int main() {
int size = sizeof (ai) / sizeof (ai[0]);
cout << "massimo di ai è: " << max( ai, size ) << endl;
// istanzia max(int*, int)
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio Istanziazione Template
14
Deduzione degli Argomenti
dagli argomenti della chiamata i tipi ed i valori da
attribuire ai parametri del template
per ogni prima occorrenza di un parametro del template
nella lista dei parametri della funzione, assegna al parametro
il tipo del corrispondente argomento della chiamata
template <class T, class U> void f(T, U, T);
f(0, ‘a’, 10);
\\ genera f(int, char, int)
f(0, ‘a’, 3.14);
\\ ERRORE
®
ü tutti
gli
argomenti
parametrizzati
devono
corrispondere esattamente al tipo assegnato al
parametro
ü il tipo del risultato non conta per la deduzione
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü E’ il processo attraverso il quale il compilatore ricava
15
8
Lllezione 12
Template
ü Quando il compilatore legge una chiamata ad un
template di funzione opera nel seguente modo
®
®
®
®
Controlla che ogni parametro del template compaia compaia
come parametro della funzione
cerca nella firma la prima occorrenza di ogni parametro del
template e gli assegna il tipo o il valore dell'argomento
corrispondente
controlla che tutte le altre occorrenze del parametro del
template corrispondano esattamente (anche con corrispondenze
banali) con i corrispondenti argomenti
cerca una corrispondenza tra i parametri della funzione non
parametrizzati ed i corrispondenti argomenti
ü Se il compilatore non è in grado di dedurre il tipo di un
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Algoritmo per Istanziazione
parametro del template segnala un ambiguità
16
template <typename Type, int size>
Type min( Type (&r_array)[size] ) {
Type min_val = r_array[0];
for ( int i = 1; i < size; ++i )
if ( r_array[i] < min_val )
min_val = r_array[i];
return min_val;
}
int ia[] = { 10, 7, 14, 3, 25 }, ia2[5] = { 10, 15, 2, 20, 16 }, *ptr;
double da[6] = { 10.2, 7.1, 14.5, 3.6, 25.4 };
…
int *ptr = ia;
int i = min( ia );
i = min( ia2 );
i = min(ptr);
i = min( da );
…
// istanzia min(int(&)[5])
// invoca la funzione min(int(&)[5]
// ERRORE
// istanzia min(double(&)[6])
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio
17
9
Lllezione 12
Template
ü Nell’invocare un template di funzione è possibile
indicare esplicitamente il valore di un parametro del
template
®
®
il compilatore non esegue l'algoritmo di deduzione ed accetta la
scelta del programmatore
Utile per risolvere le situazioni di ambiguità
template <class T>
T min(T, T);
int main() {
unsigned int ui = 1024;
min(ui, 1024);
// ERRORE
min<int>(ui, 1024);
// istanzia min(int, int)
min<unsigned int>(ui, 1024);
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Istanziazione Esplicita
18
ü Utilizzando
l'istanziazione esplicita
parametrizzare anche il tipo del risultato
®
è
possibile
istanziazioni di questo template sono corrette solo se esplicite
template <class T1, class T2, class T3> T1 min(T2, T3);
ü per le istanziazioni dei parametri del template valgono le
stesse regole dell'inizializzazione dei parametri di
funzione per default
char c; unsigned int ui;
unsigned int ris = min(c, ui);
// ERRORE
ris = min<unsigned int, char, unsigned int>min(c, ui);
ris = min<unsigned int>min(c, ui);
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Tipo del Risultato Parametrizzato
19
Laboratorio di Algoritmi e Strutture Dati
2001/02
10
Lllezione 12
Template
ü L'istanziazione esplicita può essere usata per
eliminare l'ambiguità presente nella chiamata ad
una funzione che ha argomenti parametrizzati
template <class T>
T f(T);
void g(int(*)(int));
void g(double(*)(double));
main() {
g(&f);
g(&f<int(*)(int)>);
}
// ERRORE
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione Ambiguità
20
ü E’ possibile creare versioni sovrapposte di
template di funzioni
diversi template svolgono la stessa
operazione logica ma in modi differenti
® tutte le istanze prodotte dai vari template
devono differire tra loro per numero o tipo di
argomenti
®
ü Ogni istanza di un template è una
funzione del programma che deve avere
una firma che la identifica univocamente
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Overloading di Template
21
Laboratorio di Algoritmi e Strutture Dati
2001/02
11
Lllezione 12
Template
template <class T> T min(T, T);
template <class T> T min(const T*, int);
template <typename T> T min(const vector<T>&);
int i = 0, ia[10];
i = min(3, 5); // corrisponde alla prima funzione
i = min(ia, 10); // corrisponde alla seconda funzione
template <class T, class U> int min(T, U);
i = min(3, 5); // ambigua, perché?
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio Overloading di Template
22
Specializzazione di Template
fornita dal template di funzione può essere
scorretta o inefficiente
ü E' possibile definire un’eccezione al template
®
Lo schema generale del template viene utilizzato
per generare funzioni per tutti i tipi di dati tranne
quelli per cui sono specificate le eccezioni
ü Per i tipi che fanno eccezione devono essere
definite delle specializzazioni del template
®
si può specializzare un template solo dopo aver
dichiarato lo schema generale
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Per alcuni tipi di dati la versione generale
23
Laboratorio di Algoritmi e Strutture Dati
2001/02
12
Lllezione 12
Template
Specializzazione Esplicita di
Template
definizione di una specializzazione è una
definizione di un template con i parametri istanziati
template <class T> T max(T, T);
typedef const char* PCC;
template <> PCC max<PCC>(PCC s1, PCC s2) {
return(strcmp(s1, s2) > 0 ? s1 : s2);
}
int main() {
const char* p = max("ciao", "mondo");
// chiama la specializzazione e non istanzia il template
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü La
24
ü La dichiarazione di una specializzazione deve precedere
la prima chiamata alla funzione
®
al momento della chiamata il compilatore deve sapere che deve
usare la specializzazione invece del template
ü La dichiarazione di una specializzazione deve essere
inclusa in tutti
specializzazione
®
®
i
file in cui viene utilizzata la
non è possibile usare in un file la specializzazione e in un altro
file istanziare il template
conviene inserire la dichiarazione del template e delle sue
specializzazioni nello stesso header file
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Utilizzo delle Specializzazioni
25
Laboratorio di Algoritmi e Strutture Dati
2001/02
13
Lllezione 12
Template
template <class T> T max(T, T);
int main() {
int i = max( 10, 5 ); // istanzia max( int, int );
const char *p = max( "ciao", "mondo" );
// istanzia const char* max( const char*, const char* )
cout << "i: " << i << " p: " << p << endl;
return 0;
}
typedef const char* PCC;
template<> PCC max<PCC>(PCC s1, PCC s2) { … }
// ERRORE, doppia definizione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Specializzazione Esplicita di
Template
26
Specializzazione Implicita di
Template
un'istanza del template è una specializzazione
implicita
sulle chiamate a questa funzione non valgono le
regole restrittive della deduzione dei parametri del
template
® la definizione di una specializzazione implicita
deve precedere la sua istanziazione
template <class T> T min(T, int);
®
int min(unsigned int,int);
…
int i = min(3u,i); // viene chiamata la funzione ordinaria min
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Una funzione che abbia la stessa firma di
27
14
Lllezione 12
Template
ü Nella risoluzione di un overloading il compilatore può
istanziare funzioni da un template anche se non
esplicitamente invocate
®
®
nel creare l'insieme dei candidati istanzia tutte le funzioni che
possono essere dedotte dagli argomenti della chiamata
la funzione istanziata sarà realmente invocata solo se è la
migliore funzione utilizzabile
template <class T> T sum(T, int);
double sum(double, double);
sum(3.14, 0);
// istanzia ed invoca sum(double, int)
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione dell’Overloading e
Istanziazioni
28
ü Se un template ha delle specializzazioni implicite
®
®
nella lista delle funzioni candidate viene inserita sia la
specializzazione che la funzione istanziata dal template
la specializzazione è preferita rispetto alla funzione istanziata
template <class T> T min(T, T);
int min(int, int);
min(3, 2);
/* la specializzazione e l'istanza del template
sono candidate la specializzazione è
invocata */
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione dell’Overloading e
Specializzazioni Implicite
29
Laboratorio di Algoritmi e Strutture Dati
2001/02
15
Lllezione 12
Template
ü Se un template ha delle specializzazioni esplicite
®
®
nella lista delle funzioni candidate viene inserita la
specializzazione e non la funzione istanziata dal template
la specializzazione è una candidata solo se la sua firma può
essere dedotta dalla chiamata
template <class T> T min(T, T);
template <> double min<double>(double, double);
int min(int, int);
min(3.14, 2); // no match
min(3.14, 2.5); // la specializzazione è candidata
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione dell’Overloading e
Specializzazioni Esplicite
30
1. Costruisce l'insieme delle funzioni candidate
®
®
funzioni con lo stesso nome della funzione chiamata
istanze di template con lo stesso nome della funzione chiamata e
che possono essere dedotte dalla chiamata
2. Costruisce l'insieme delle funzioni utilizzabili
®
seleziona le funzioni candidate i cui parametri corrispondono
per tipo e numero agli argomenti della chiamata
3. Classifica il tipo di corrispondenza di ogni funzione
utilizzabile
4. Seleziona la migliore funzione utilizzabile
®
®
®
se ne esiste una sola la chiamata è risolta
se ce ne sono più di una la chiamata è ambigua
se non ce ne sono la chiamata non è risolta
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione di una Chiamata ad
una Funzione
31
Laboratorio di Algoritmi e Strutture Dati
2001/02
16
Lllezione 12
Template
template <class T> T min(T, T);
double min(double, double);
main() {
int i; double d; float f;
min(0, i);
// due candidate, invoca l'istanza del template per T = int
min(3.14, d);
// invoca la specializzazione
min(0, f);
// specializzazione unica candidata
}
char min(char, char);
// cosa succede alla terza chiamata?
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio
32
Quando Creare Template di
Classi
contenitore che possono essere utilizzate per
contenere qualunque tipo di dati
template <class T>
class Coda{
T* vett;
…
};
ü Si possono utilizzare i template di classi per creare
librerie di classi generiche
® l’utente della libreria potrà utilizzare la classe della libreria
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Un template di classe permette di creare classi
istanziandola per qualunque tipo di dati
33
Laboratorio di Algoritmi e Strutture Dati
2001/02
17
Lllezione 12
Template
Definizione di un Template di
Classi
strutturata come la definizione di una classe normale
®
®
contiene lista dei parametri del template
i parametri possono essere utilizzati nella definizione
template <class T>
class Coda {
public:
Coda();
~Coda();
void inserisci( const T& );
T& rimuovi();
bool vuota();
private:
…
};
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü La definizione (dichiarazione) di un template di classi è
34
template <class T>
class CodaItem {
public:
friend class Coda<T>;
CodaItem(const T&);
private:
CodaItem<T>* succ;
T item;
};
template <class T>
class Coda {
public:
Coda();
~Coda();
void inserisci( const T& );
T& rimuovi();
bool vuota();
private:
CodaItem<T>* testa;
CodaItem<T>* coda;
};
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Definizione Classe Coda
35
Laboratorio di Algoritmi e Strutture Dati
2001/02
18
Lllezione 12
Template
ü Quando il compilatore legge la definizione di un
template di classi non alloca memoria
ü Un’istanza del template viene creata solo quando il
programma definisce una variabile della classe
®
®
per definire una variabile della classe bisogna specificare tutti i
valori da assegnare ai parametri del template
La definizione di un puntatore o un riferimento non istanzia il
template
Coda<int> qi;
Coda<string> qs;
Coda<double>* pqd;
Coda q;
// non istanzia il template
// ERRORE
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Istanziazione di un Template di
Classi
36
ü L’istanziazione di un template può essere utilizzato
come specificatore di tipo
ü Non è possibile far riferimento al template della
classe al di fuori dello scope del template
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Istanziazione di un Template di
Classi
37
Laboratorio di Algoritmi e Strutture Dati
2001/02
19
Lllezione 12
Template
ü Il punto di istanziazione di un template è il momento in
cui viene generata la classe
®
®
Definizione di una variabile
Dereferenziazione di un puntatore o di un riferimento
ü Nel punto di istanziazione del template deve essere
visibile la definizione del template
®
Nel C++ pre-standard dovevano essere visibili anche le
definizioni dei metodi
ü La definizione di una classe va inserita in un file di
intestazione mentre le definizioni dei suoi metodi vanno
inseriti in un file di implementazione
®
Ogni file in cui si istanzia il template include la definizione della
classe
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Punto di Istanziazione di un
Template di Classi
38
ü I metodi di un template di classi sono template di
funzioni
®
Possono essere definiti inline all’interno della definizione del
template o esterni alla definizione
template <class T>
class Coda {
public:
Coda() : testa(0), coda(0) {};
~Coda();
void inserisci( const T& );
T& rimuovi();
bool vuota() { return front == 0; }
private:
CodaItem<T>* testa;
CodaItem<T>* coda;
};
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Metodi di Template di Classi
39
20
Lllezione 12
Template
template <class T>
Coda<T>::~Coda() {
while( !vuota() ) rimuovi();
}
template <class T>
void Coda<T>::inserisci(const T& val) {
CodaItem<T> *pt = new CodaItem<T>(val);
if(vuota())
testa = coda = pt;
else {
coda->succ = pt;
coda = pt;
}
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Metodi di Template di Classi
40
template <class T>
T& Coda<T>::rimuovi() {
if(vuota()) {
cerr << “coda vuota” << endl;
exit(-1);
}
CodaItem<T> *pt = testa;
testa = testa->succ;
T val = pt->item;
delete pt;
return val;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Metodi di Template di Classi
41
Laboratorio di Algoritmi e Strutture Dati
2001/02
21
Lllezione 12
Template
ü Esistono tre tipi di dichiarazioni di amicizia che possono
com parire nella definizione di un template di classi
class F;
template <class T>
class CodaItem {
friend class F;
friend void f();
friend void F::f();
};
ü Le classi e le funzioni non template sono amiche di ogni
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Relazioni di Amicizia per
Template di Classi
istanza del template
42
ü I metodi di un template di classi vengono
istanziati quando sono invocati per la prima
volta
®
L’istanziazione dei metodi segue le
dell’istanziazione dei template di funzioni
regole
ü Il C++ pre-standard istanzia tutti i metodi del
template di classi contemporaneamente alla
istanziazione della classe
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Istanziazione dei Metodi di un
Template di Classi
43
Laboratorio di Algoritmi e Strutture Dati
2001/02
22
Lllezione 12
Template
template <class T> class F;
template <class T> void f(CodaItem<T>);
template <class T>
class Coda {
friend class F<T>;
friend void f(CodaItem<T>);
friend void F<T>::f();
};
Ogni istanza della classe F è amica della corrispondente
classe Coda
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Relazioni di Amicizia per
Template di Classi
44
template <class T>
class CodaItem {
template <class U> friend class F;
template <class U> friend void f(CodaItem<U>);
template <class U> friend void F<U>::f();
};
Tutte le istanze della classe F sono amiche di ogni
istanza della classe CodaItem
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Relazioni di Amicizia per
Template di Classi
45
Laboratorio di Algoritmi e Strutture Dati
2001/02
23
Lllezione 12
Template
template <class T>
class CodaItem {
friend class Coda<T>;
friend ostream& operator<<(ostream&, CodaItem<T>&);
private:
CodaItem(const T&);
CodaItem<T>* succ;
T item;
};
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Relazioni di Amicizia tra Coda e
CodaItem
46
template <class T>
ostream& operator<<( ostream &os, const CodaItem<T> &qi ) {
os << qi.item;
return os;
}
template <class T>
ostream& operator<<( ostream &os, const Coda<T> &q ) {
os << "< ";
CodaItem<T> *p;
for ( p = q.testa; p; p = p->succ )
os << *p << " ";
os << " >";
return os;
}
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Output di Coda e CodaItem
47
24
Lllezione 12
Template
ü Un template di classi può dichiarare dei membri static
®
®
ogni istanza del template avrà le proprie copie dei dati static
i dati static sono comuni solo tra variabili dello stesso tipo di
istanziazione
ü I dati static vengono istanziati solo quando vengono
usati per la prima volta
ü La sintassi per inizializzare un dato static di un
template è
template <class T>
int Coda<T>::cont = 1;
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Elementi static di un Template
48
template <class T>
class CodaItem {
friend class Coda<T>;
friend ostream& operator<<(ostream&, CodaItem<T>&);
private:
static const unsigned int _blocco;
static CodaItem<T>* free_list;
CodaItem(const T&);
void* operator new(size_t);
void operator delete(void*, size_t);
CodaItem<T>* succ;
T item;
};
template <class T> CodaItem<T>* CodaItem<T>::free_list = 0;
template <class T> const unsigned int CodaItem<T>::_blocco = 24;
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Membri static di CodaItem
49
Laboratorio di Algoritmi e Strutture Dati
2001/02
25
Lllezione 12
Template
template <class T>
void* CodaItem<T>::operator new( size_t size ) {
CodaItem<T> *p;
if ( ! free_list ) {
size_t blo = _blocco * size;
free_list = p = reinterpret_cast<CodaItem<T>* > ( new char[blo] );
for ( ; p != &free_list[ CodaItem_blocco - 1 ]; ++p )
p->succ = p + 1;
p->succ = 0;
}
p = free_list;
free_list = free_list->succ;
return p;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Uso Membri static di CodaItem
50
template <class T>
void CodaItem<T>::operator delete( void *p, size_t ) {
static_cast< CodaItem<T>* >( p )->succ = free_list;
free_list = static_cast< CodaItem<T>* > ( p );
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Uso Membri static di CodaItem
51
Laboratorio di Algoritmi e Strutture Dati
2001/02
26
Lllezione 12
Template
ü Il C++ standard consente la definizione di metodi
template all’interno di classi (sia template che
non template)
®
®
Tecnica ampiamente utilizzata nella libreria standard
per supportare la programmazione generica
Non supportata da compilatori pre-standard
ü Ogni istanza della classe template contiene tutte
le istanze del metodo template
®
Il metodo template è istanziato quando viene invocato
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Membri Template
52
ü E’ possibile definire delle versioni specializzate del
template della classe
template <> class Coda<LongDouble> { … };
® La specializzazione deve seguire la definizione del template
® La specializzazione deve essere inseritain tutti i file del
programma
® In questo caso bisogna fornire le specializzazioni per tutti i
metodi del template della classe
ü E’ possibile definire anche solo la specializzazione di
alcuni metodi della classe
class LongDouble;
template <> LongDouble Coda::remove() { … }
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Specializzazione di un Template
di Classi
53
Laboratorio di Algoritmi e Strutture Dati
2001/02
27
Lllezione 12
Template
ü Se il template ha più parametri è possibile
fornire una specializzazione per solo uno dei
parametri
®
Può fornire implementazioni più efficienti per
specifici valori del parametro
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Specializzazioni Parziali
54
ü Ogni istanza del template ha un proprio scope locale
ü il compilatore cerca di risolvere, se possibile, i nomi
quando legge la definizione del template
®
®
®
i nomi non dipendenti dal template sono risolti subito
i nomi dipendenti dal template sono risolti dopo l'istanziazione
Un nome potrebbe essere risolto con una variabile non visibile al
momento della definizione del template
template <class T> T min(T* array, int size) {
// size non dipende dal template
T minVal = array[0];
// minVal dipende dal template
for(int i = 1; i < size; i++)
if(array[i] < minVal)
minVal = array[i];
return minVal;
}
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione dei Nomi nei
Template
55
28
Lllezione 12
Template
Risoluzione dei Nomi nei
Template
®
®
se tra gli argomenti non ci sono variabili dipendenti dal
template la funzione deve essere dichiarata prima della
definizione del template
se tra gli argomenti ci sono variabili dipendenti dal template
la funzione deve essere dichiarata prima della istanziazione
del template
template <class T> T min(T* array, int size) {
T minVal = array[0]; // minVal dipende dal template
for(int i = 1; i < size; i++)
if(array[i] < minVal) minVal = array[i];
print(minVal);
// print non dichiarata
return minVal;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Quando il template contiene una chiamata a funzione
56
Modelli di Compilazione di
Template
momento dell'istanziazione del template il
compilatore deve produrre il codice del'istanza
®
®
deve conoscere la definizione del template
il compilatore deve interrompere la compilazione, risolvere i
valori da assegnare ai parametri e generare la classe
ü La
definizione di una
allocazione di memoria
®
classe
non
determina
La definizione di una classe può essere inserita più volte
all’interno dello stesso programma
ü La definizione di un template di classe va inserita in
un file di intestazione
®
Il file viene incluso in tutti i file in cui deve essere istanziato il
template
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Al
57
29
Lllezione 12
Template
ü I metodi del template di classi e i membri static
si comportano come template di funzioni
®
®
Le definizioni devono essere visibili nel punto in cui
vengono istanziati
I metodi sono istanziati solo quando vengono
invocati per la prima volta
ü Il C++ standard supporta due modelli di
compilazione dei template di funzioni
®
®
modello ad inclusione
modello a separazione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Modelli di Compilazione di
Template
58
ü La definizione di un metodo del template deve essere
inclusi in ognuno dei file in cui il template è istanziato
®
®
il template viene inserito in un header file
la definizione del template è trattata come le funzioni inline
ü Se l'header file viene incluso in più di un file il
compilatore deve generare una sola copia di ogni istanza
del template
®
®
L’implementazione dipende dal compilatore
molti compilatori generano istanze del template in ogni file. Il
linker seleziona una sola istanza e la utilizza per tutte le chiamate
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Modello ad Inclusione
59
Laboratorio di Algoritmi e Strutture Dati
2001/02
30
Lllezione 12
Template
ü Il g++ supporta il modello ad inclusione
® istanzia i template in tutti i file in cui sono richiesti
® solo una di queste istanziazioni è utilizzata
ü Questo modello di compilazione è inefficiente sia
per tempo che per spazio
ü Possibile migliorare i tempi di compilazione
dicendo al compilatore di non generare tutte
queste copie
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Modello ad Inclusione in g++
60
Istanziazione Esplicita
in un file è possibile inserire una dichiarazione di
istanziazione esplicita
®
Istanzia sia la classe che tutti i suoi metodi
ü Le definizioni dei metodi devono essere visibili
®
®
l’istanziazione esplicita si deve trovare nello stesso file della
definizione dei template di funzione
In genere si inserisce la definizione del template in un file di
implementazione insieme alle istanziazioni esplicite
template class Coda<int>;
ü Bisogna garantire che il compilatore non istanzi gli stessi
metodi anche in altri file
® si usa un opzione di compilazione per dire al compilatore di
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Per obbligare il compilatore a generare una certa istanza
istanziare template solo se il programma ne fa richiesta esplicita
® in g++ Opzione no_implicit_istantiation
Laboratorio di Algoritmi e Strutture Dati
2001/02
61
31
Lllezione 12
Template
ü La dichiarazione del template viene inclusa in ogni file
dove il template è utilizzato. La definizione viene inclusa
in un file di implementazione linkato al programma
®
®
le istanze del template sono gestite come le funzioni non inline
la definizione del template deve essere resa visibile a tutti i file
export template <class T> T min(T x, T y) { … }
export template <class T> Coda { … };
su molti compilatori questa organizzazione non
funziona (Es. g++)
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Modello a Separazione
62
file min.h
template <class T> T min(T, T);
file min.C
export template <class T> T min(T a, T b) {
return (a < b ? a : b); }
#include “min.h”
file main.C main() {
int i = min(3, 6);
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio
63
Laboratorio di Algoritmi e Strutture Dati
2001/02
32