Newsgroup: it.comp.lang.c++
Titolo: Overloading di funzioni e Template

Faccio subito un esempio pratico:
Mettiamo che io volessi scrivere una semplicissima funzione che prende in
ingresso due dati numerici e mi stampa la somma:
void sum (int a, int b) {
cout << a+b;
}
Volendo ricoprire i 4 casi possibili (int-int, float-int, int-float,
float-float), scrivo 4 volte questa funzione, con lo stesso nome per motivi
di comodità e di riusabilità del codice (cioè se qualcun altro dovesse
riutilizzarlo sarebbe + facilitato), cioè faccio un overloading della
funzione.
Se io invece usassi i template, così:
template<class X, class Y>
void sum (X a, Y b) {
cout << a+b;
}
(poi chiaramente nel main due parametri locali c, d con il loro tipo
determinano quello di a e b)
non risparmierei molto codice? La mia domanda quindi è, se è tutto giusto
ciò che ho appena detto: i template rendono inutile l'overloading delle
funzioni?
Thankx,
Robhert

 Thankx,
No l'overloading serve lo stesso. E' attraverso il meccanismo 
dell'overloading che possono coesistere funzioni con lo stesso nome, ma con 
argomenti diversi. Poi dipende da te generarli esplicitamente, o attraverso 
i template.
Inoltre con l'oerloading esplicito puoi fare cose che non puoi fare con i 
template
Poniamo il tuo caso 
template<class X, class Y>
  void sum (X a, Y b) {
        cout << a+b;
  }
Se poi vuoi fare una cosa del tipo 
        sum( "1","2" );
In cui vorresti ottenere 3 ?
Per farlo devi AGGIUNGERE esplicitamente questo overload
void sum (char * a, char * b) {
        cout << atoi(a)+atoi(b);
}

 l'overloading delle funzioni?
no. E` proprio grazie all'overloading che i template possono funzionare: 
se tu hai:
template<class X, class Y>
void sum (X a, Y b) {
cout << a+b;
}
e poi scrivi
        sum(1,2);
        sum(1.0, 2);
        sum(1, 2.0);
        sum(1.0, 2.0);
il compilatore genera a partire dal template quattro diverse funzioni con 
lo stesso nome e parametri differenti: in pratica e` come se tu le 
avessi scritte esplicitamente, per cui e` facile capire che se non ci 
fosse l'overloading il compilatore non potrebbe generare quattro 
funzioni con lo stesso nome.
ciao Anto
-- 
Antonio Cuni, 20 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 no. E` proprio grazie all'overloading che i template possono funzionare:
Perfetto, il concetto mi era già chiarissimo. Tuttavia quello che mi
chiedevo e mi chiedo tutt'ora: preso atto che i template sfruttano
l'overloading delle funzioni, ora che posso usare i template non scriverò
più volte la stessa funzione. Cioè con i template a cosa serve *scrivere*
funzioni con lo stesso nome (cioè fare l'overloading esplicito)?
Doggett

Beh, considera i casi in cui l'implementazione della funzione non va bene
per qualsiasi tipo. La soluzione può essere o una specializzazione del
template per quel tipo oppure una funzione ordinaria che sarà, insieme a
tutte le istanze della funzione template, candidata all'overloading. In
genere, scrivere una funzione ordinaria è più semplice della sua equivalente
sottoforma di template specializzata per quel tipo. Inoltre, per le funzioni
ordinare ci sono delle regole di conversione meno restrittive rispetto ai
parametri delle funzioni template. Infatti hai:
1) Promozioni
2) Conversioni standard
3) Conversioni di qualificazione (quando i parametri sono const o volatile).
Inoltre, nel caso delle funzioni template specializzate, ricorda che vengono
totalmente ignorate se non c'è corrispondenza (perfetta, o tramite cast) tra
la chiamata e il template generale.
In definitiva, le funzioni template non sostituiscono *completamente* le
funzioni ordinarie.
Ciao
--
Luigi

 funzioni con lo stesso nome (cioè fare l'overloading esplicito)?
Semplicemene: non è detto che una funzione SUPERGENERICA sia sempre
applicabile al problema in oggetto. Pensa a confrontare due stringhe stile
C, ed una funzione isEq che confronta:
template <class T>
int isEq(T a, T b) {
    return a==b;
}
char *a, *b;
...
...
isEq(a, b);
Probabilmente il comportamento non è quello voluto (vengono confrontati i
puntatori e non le stringhe). Quindi devo fare una versione specifica.
int isEq(char *a, char *b) {
    return !strcmp(a,b);
}
Ok?
Luigi Mantellini
Per il pessimista il bicchiere è mezzo vuoto,
per l'ottimista è mezzo pieno,
per un ingegnere è semplicemente sovradimensionato rispetto l'uso.