1 of 20

PROGRAMMAZIONE GENERICA�Template functions �e overloading di operatori

3^ INFORMATICO - IIS PASCAL�DIPARTIMENTO INFORMATICA

2 of 20

2

ARGOMENTI

  • Concetto di programmazione generica
  • Definizione di funzione template
  • Overloading di operatori

​

3 of 20

3

DEFINIZIONE

Per programmazione “generica” si intendono una serie di �pratiche atte a definire strutture e funzioni che possono essere utilizzati con variabili di tipi diversi senza necessità�di ridefinizione

​

​

“Questo approccio, introdotto nel linguaggio ML nel 1973,[1][2] permette di scrivere codice generico, del quale possono essere auto-generate multiple versioni specializzate che differiscono solo per i tipi di dati trattati, riducendo così la necessità di scrivere codici essenzialmente duplicati.”[Wikipedia]

​

4 of 20

Template functions

​

​

5 of 20

Cos'è una "funzione template" ?

Scopriamolo con un esercizio...

​

Immaginiamo di voler scrivere una funzione �void scambia(int, int) che riceve due variabili

intere e ne scambia il valore

​

​

​

​

​

​

​

​

​

​

​

​

benissimo, andiamo avanti…

6 of 20

Cos'è una "funzione template" ?

Scopriamolo con un esercizio...

​

Immaginiamo di voler scrivere una funzione �void scambia(float, float) che riceve due variabili

float e ne scambia il valore

​

​

​

​

​

​

Ottimo lavoro!

andiamo avanti…

7 of 20

Cos'è una "funzione template" ?

Scopriamolo con un esercizio...

​

Immaginiamo di voler scrivere una funzione �void scambia(string, string) che riceve due variabili

string e ne scambia il valore

​

​

​

​

​

​

Wow…

e sono tre...

andiamo avanti…

8 of 20

Cos'è una "funzione template" ?

Scopriamolo con un esercizio...

​

Immaginiamo di voler scrivere una funzione �void scambia(double, double) che riceve due variabili

double e ne scambia il valore

​

​

​

​

​

​

Sono tutte uguali!!

​

Cambia solo il tipo !

​

ne servirebbe una generica…

​

Come si fa???

9 of 20

Programmazione generica

C++ mette a disposizione la sintassi per creare funzioni generiche

​

Per queste si deve specificare il comportamento �senza preoccuparsi del tipo.

​

​

​

​

​

​

​

​

Unica attenzione:

​

tutte le operazioni all'interno della funzione devono essere legali rispetto al tipo generico

​

legali significa che il compilatore deve sapere come si esegue una certa operazione per quel certo tipo di dato

template<typename T>

return_type function_name(T var_name, <var_list>) {

code...

}

10 of 20

Programmazione generica

Riscriviamo la nostra funzione scambio con la programmazione generica

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

NOTA: nella funzione template si usa solo l'assegnazione che è ben definita sia per gli int che per i float

template<typename T>

void scambia(T& x, T& y) { // per riferimento

T tmp = x;

x = y;

y = tmp;

}

​

int main() {

int a = 2; int b = 3;

scambia(a, b);

cout << " A = " << a << " B = " << b << endl;

float c = 2.5; float d = 3.6;

scambia(c, d);

cout << " C = " << c << " D = " << d << endl;

}

OUTPUT:

A = 3 B = 2

C = 3.6 D = 2.5

11 of 20

Programmazione generica : esercizio

Scrivere una funzione generica occorrenze (template function) che riceve

  • un array A di elementi di tipo T
  • un elemento E di tipo T
  • un intero pari alla dimensione dell'array A

e restituisce un numero intero delle occorrenze di E in T

​

La funzione deve essere utilizzabile con il seguente codice

​

​

​

​

​

​

​

producendo il seguente output

int vettint[ ] {1,2,3,3,2,3,4,3};

int oc1 = occorrenze(vettint, 3, 8);

cout << "Il numero 3 è presente " << oc1 << " volte\n";

​

string s[ ] {"ciao", "come", "state", "come", "oggi", "come", "ieri"};

string s1 = "come";

int oc2 = occorrenze(s, s1, 7);

cout << "La stringa 'come' è presente " << oc2 << " volte\n";

�OUTPUT:

Il numero 3 è presente 4 volte�La stringa 'come' è presente 3 volte

12 of 20

Programmazione generica : soluzione

La programmazione generica ci consente di passare un array di elementi di tipo qualsiasi e un elemento dello stesso tipo da confrontare.

​

NOTA: nella funzione template si usa l’operatore di confronto che è ben definito sia per gli int che per le stringhe

​

​

template<typename T>

int occorrenze(T x[], T elem, int size) { // il passaggio per array è sempre per riferimento

int cont = 0;

for (int i = 0; i<size; i++) {

if (x[i] == elem) cont++;

}

return cont;

}

13 of 20

Programmazione generica : esercizi

  1. Scrivi una funzione template ordina per ordinare un vettore qualsiasi in senso ascendente o discendente
  2. scrivi una funzione template colonnaMassima che prende in input una matrice di elementi qualsiasi e restituisce l'indice della colonna per la quale è massima la somma�hint: qual è il valore di riferimento per i tipi generici??? soluzione
  3. scrivi una funzione template isOrdinato che prende un array generico e la sua dimensione e restituisce True se l'array è ordinato, False altrimenti

​

​

​

14 of 20

Overloading di operatori

​

​

15 of 20

Overloading di operatori

Parlando di template functions abbiamo evidenziato che tutte le operazioni all'interno della funzione devono essere legali rispetto al tipo generico

​

In alcuni casi succederà che l’operazione della funzione generica NON sia di default permessa per un certo tipo dato

​

Come possiamo fare?

​

Dobbiamo fare in modo che il compilatore sappia come interpretare un operatore su un tipo dato nuovo

16 of 20

Overloading di operatori

Facciamo l’esempio della funzione generica differenza

template<typename T>

T differenza(T a, T b) {

return a-b;

}

int main() {

int a = 5;

int b = 3;

cout << differenza(a, b) << endl;

​

return 0;

}

​

�OUTPUT:

2

17 of 20

Overloading di operatori

Facciamo l’esempio della funzione generica differenza

template<typename T>

T differenza(T a, T b) {

return a-b;

}

int main() {

​

int a = 5;

int b = 3;

cout << differenza(a, b) << endl;

​

string s = "Ciao";

string t = "Raga";

cout << differenza(s, t) << endl;

return 0;

}

​

�OUTPUT:

/home/giulio/Documenti/Didattica/Scuola/Didattica/Dispense/01_Informatica/__3_INFO/Template_functions/3INFO_overloading_base/main.cpp|24|error: no match for ‘operator-’ (operand types are ‘std::__cxx11::basic_string<char>’ and ‘std::__cxx11::basic_string<char>’)|

18 of 20

Overloading di operatori

Facciamo l’esempio della funzione generica differenza

template<typename T>

T differenza(T a, T b) {

return a-b;

}

string operator-(string x, string y) {

return "Uhm! che operazione bizzarra!!!";

}

int main() {

int a = 5;

int b = 3;

cout << differenza(a, b) << endl;

​

string s = "Ciao";

string t = "Raga";

cout << differenza(s, t) << endl;

return 0;

}

​

�OUTPUT:

2

Uhm! che operazione bizzarra!!!

​

19 of 20

Overloading di operatori

Esercizio:

​

definisci l’operatore * per permettere la moltiplicazione fra stringa�e intero

​

​

es:

string s = “ciao”;

string t = s*3;

​

t deve essere ciaociaociao

​

​

​

10 minuti…

​

soluzione

20 of 20

Overloading di operatori

Esercizio:

​

definisci l’operatore - per permettere la differenza fra due stringhe �dove si intenda la differenza carattere per carattere

Si assumano le due stringhe della stessa lunghezza

​

es:

string s = “otto”;

string t = “abba”;

​

s - t deve essere nrrn

​

​

​

10 minuti…

​

soluzione