Menu
Coddy logo textTech

Template di funzione

Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 64 di 104.

Immagina di scrivere una funzione per trovare il massimo tra due numeri interi, per poi renderti conto che ti serve la stessa logica per i numeri double e, ancora, per le stringhe. Senza i template, dovresti scrivere funzioni quasi identiche per ogni tipo. I template di funzione risolvono il problema consentendoti di scrivere la logica una sola volta e di fare in modo che il compilatore generi automaticamente versioni specifiche per ciascun tipo.

Un modello di funzione usa la parola chiave template seguita dai parametri del modello tra parentesi angolari:

template <typename T>
T maximum(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    std::cout << maximum(5, 3) << std::endl;       // Usa la versión int
    std::cout << maximum(3.14, 2.71) << std::endl; // Usa la versión double
    std::cout << maximum('a', 'z') << std::endl;   // Usa la versión char
}

Il compilatore esamina ogni chiamata e genera una funzione concreta per quel tipo specifico. Questo processo si chiama istanziazione del template. Puoi anche specificare esplicitamente il tipo quando necessario:

std::cout << maximum<double>(5, 3.14) << std::endl;  // Forza la versione double

I modelli possono avere più parametri di tipo, consentendo progetti ancora più flessibili:

template <typename T, typename U>
void printPair(T first, U second) {
    std::cout << first << ", " << second << std::endl;
}

printPair(42, "hello");    // T=int, U=const char*
printPair(3.14, 100);      // T=double, U=int

I modelli di funzione forniscono polimorfismo in fase di compilazione: il tipo viene determinato quando il codice viene compilato, non durante l'esecuzione. Ciò significa zero overhead durante l'esecuzione rispetto alle funzioni virtuali, rendendo i modelli ideali per il codice generico in cui le prestazioni sono fondamentali.

challenge icon

Sfida

Facile

Costruiamo un kit di utilità usando i template di funzione per creare operazioni riutilizzabili che funzionano con qualsiasi tipo compatibile. Organizzerai le tue funzioni generiche in un file header e ne dimostrerai la flessibilità nel programma principale.

Creerai due file:

  • MathUtils.h: Definisci una raccolta di template di funzione che eseguono operazioni comuni:

    minimum: una funzione template che accetta due valori dello stesso tipo e restituisce quello più piccolo.

    clamp: una funzione template che accetta tre parametri: un valore, un limite inferiore e un limite superiore. Restituisce il valore vincolato entro i limiti (restituisce il limite inferiore se il valore è minore del limite inferiore, il limite superiore se il valore è maggiore del limite superiore, altrimenti restituisce il valore stesso).

    swapValues: una funzione template che accetta due riferimenti dello stesso tipo e scambia i loro valori.

  • main.cpp: Leggi sei input (ciascuno su una riga separata):

    1. Primo intero
    2. Secondo intero
    3. Un valore double da limitare
    4. Limite inferiore (double)
    5. Limite superiore (double)
    6. Un carattere

    Dimostra i tuoi template:

    1. Trovando il minimo dei due interi e stampando: Min of <a> and <b>: <result>
    2. Trovando il minimo dei caratteri 'm' e del carattere inserito, stampando: Min of m and <char>: <result>
    3. Limitando il valore double e stampando: Clamp <value> to [<low>, <high>]: <result>
    4. Limitando il primo intero all'intervallo [0, 100] e stampando: Clamp <value> to [0, 100]: <result>
    5. Scambiando i due interi e stampando: After swapValues: <a>, <b>

Ad esempio, con gli input 25, 10, 3.7, 1.0, 5.0 e z:

Min of 25 and 10: 10
Min of m and z: m
Clamp 3.7 to [1, 5]: 3.7
Clamp 25 to [0, 100]: 25
After swapValues: 10, 25

Nota come ogni funzione template funzioni senza problemi con interi, double e caratteri: il compilatore genera la versione appropriata per ogni tipo utilizzato. La tua funzione swapValues dovrebbe modificare le variabili originali tramite riferimenti, dimostrando che i template funzionano con parametri di riferimento proprio come le funzioni normali.

Provalo tu

#include <iostream>
#include "MathUtils.h"
using namespace std;

int main() {
    // Leggi gli input
    int a, b;
    double value, low, high;
    char ch;
    
    cin >> a;
    cin >> b;
    cin >> value;
    cin >> low;
    cin >> high;
    cin >> ch;
    
    // TODO: Usa il template minimum per trovare il minimo tra due numeri interi
    // Stampa: "Min of <a> and <b>: <result>"
    
    // TODO: Usa il template minimum per trovare il minimo tra 'm' e il carattere di input
    // Stampa: "Min of m and <char>: <result>"
    
    // TODO: Usa il template clamp sul valore double
    // Stampa: "Clamp <value> to [<low>, <high>]: <result>"
    
    // TODO: Usa il template clamp sul primo numero intero nell'intervallo [0, 100]
    // Stampa: "Clamp <value> to [0, 100]: <result>"
    
    // TODO: Usa il template swapValues sui due numeri interi
    // Stampa: "After swapValues: <a>, <b>"
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C++ online