Storia della questione
Il C++ è stato progettato fin dall'inizio come un linguaggio che supporta il sovraccarico di funzioni, ovvero la possibilità di dichiarare più funzioni con lo stesso nome ma con parametri diversi. Questo consente di creare API leggibili e convenienti.
Problema
Quando ci sono molte funzioni con lo stesso nome, il compilatore deve scegliere l'implementazione appropriata tra tutte le sovraccaricate, tenendo conto dei tipi di argomenti, delle conversioni, dei parametri predefiniti e dei riferimenti. Con sovraccarichi distratti possono verificarsi ambiguità e errori difficili da individuare.
Soluzione
Il compilatore seleziona la funzione sulla base della migliore corrispondenza della sequenza di argomenti, della precisione della corrispondenza del tipo e delle trasformazioni minime. Tuttavia, è necessario considerare alcune sfumature: se ci sono conversioni significative o argomenti predefiniti, si può inaspettatamente ottenere ambiguità.
Esempio di codice:
void foo(int x); void foo(double x); void foo(int x, int y = 0); foo(5); // chiamerà void foo(int x), perché è una corrispondenza esatta foo(5.2); // chiamerà void foo(double x) foo(5, 6); // chiamerà void foo(int x, int y)
Caratteristiche chiave:
È possibile sovraccaricare le funzioni solo in base al tipo restituito?
No. Il sovraccarico è possibile SOLO in base al tipo e al numero di parametri, il tipo restituito non partecipa alla risoluzione del sovraccarico.
int foo(); double foo(); // Errore: il sovraccarico solo per il return type non è possibile!
Come sceglie il compilatore quale funzione sovraccaricata chiamare se tutti i parametri sono convertibili?
Il compilatore sceglie "la migliore corrispondenza" — la funzione per cui sono necessarie il minor numero di trasformazioni di tipo, oppure una corrispondenza esatta. Se esiste ambiguità, il codice non verrà compilato.
void bar(int); void bar(long); bar(1); // int corrispondenza esatta: verrà chiamato bar(int)
È possibile mescolare sovraccarico con argomenti predefiniti e sovraccarico normale?
Sì, ma si può incorrere in ambiguità di chiamata se le firme delle funzioni si sovrappongono.
void test(int x); void test(int x, int y = 10); test(5); // Errore: ambiguità — entrambe si adattano
Nella libreria si incontrano funzioni sovraccaricate con argomenti predefiniti sovrapposti, il che porta a errori di compilazione durante l'aggiornamento del codice.
Pro:
Contro:
Nel progetto è stato stabilito un accordo: non mescolare sovraccarichi con argomenti predefiniti, oppure utilizzare solo una funzione con valori predefiniti, oppure sovraccaricare esclusivamente su parametri unici.
Pro:
Contro: