Domanda

Perché non vediamo linguaggi di tipo C che consentono callable con polimorfismo nel tipo restituito? Ho potuto vedere come l'inferenza del tipo aggiuntivo sarebbe un ostacolo, ma abbiamo molte lingue con sistemi di inferenza di tipo completo (che funzionano per vari livelli di "lavoro").

Modifica: Per polimorfismo del tipo restituito intendo sovraccaricare la firma della funzione solo nel tipo restituito. Ad esempio, C ++ e Java consentono solo il sovraccarico nel tipo di parametri formali, non nel tipo restituito.

È stato utile?

Soluzione

Se per " tipo di polimorfismo di ritorno " intendi sovraccarico in base al tipo di valore restituito, non sono sicuro di altre lingue, ma per C ++ ecco la risposta (praticamente dalla bocca del cavallo):

I tipi di restituzione delle funzioni non entrano in gioco nella risoluzione del sovraccarico semplicemente perché Stroustrup (presumo con input da altri architetti C ++) voleva che la risoluzione del sovraccarico fosse "indipendente dal contesto". Vedi 7.4.1 - "Sovraccarico e tipo di ritorno" dal "linguaggio di programmazione C ++, terza edizione".

  

Il motivo è mantenere la risoluzione per   un singolo operatore o funzione   chiamare indipendente dal contesto.

Volevano che si basasse solo sul modo in cui veniva chiamato il sovraccarico, non sul modo in cui veniva usato il risultato (se usato affatto). In effetti, molte funzioni vengono chiamate senza utilizzare il risultato o il risultato verrebbe utilizzato come parte di un'espressione più grande. Un fattore che sono certo entrato in gioco quando hanno deciso che era che se il tipo restituito fosse parte della risoluzione ci sarebbero state molte chiamate a funzioni sovraccariche che avrebbero dovuto essere risolte con regole complesse o avrebbero dovuto essere lanciate dal compilatore un errore che la chiamata era ambigua.

E, lo sa Lord, la risoluzione del sovraccarico in C ++ è abbastanza complessa così com'è ...

Altri suggerimenti

Mi piacerebbe vedere questa funzione in un linguaggio, non solo in modo che la funzione foo potesse restituire un doppio o un int o una stringa, ma anche in modo che foo potesse restituire una struttura o oggetti di classi diverse. Le chiamate non ambigue sarebbero piuttosto banali: se la chiamata è ambigua, richiedere un cast per selezionare il tipo di ritorno desiderato. Esempio:

string s = foo();    //foo returns a string
double x = foo();    //foo returns a double
int i = foo();       //foo returns an integer
float f = (float)(int)foo();    //call the int foo and convert to float

in aggiunta

Animal a = fooFactory();    //fooFactory returns an Animal
Plant p = fooFactory();     //foofactory returns a Plant

queste situazioni non si presentano molto spesso, ma quando lo fanno la soluzione è spesso piuttosto brutta ...

double x = (double)foo();

Quanto sopra è ambiguo se ci sono versioni di foo () che possono restituire double, int, float, ecc.

In C ++ puoi farlo in gran parte con le classi. Ad esempio, supponiamo di avere un tipo di dati che viene regolarmente convertito in ASCII su input e output;

typedef char* pchar;

class   MyType
{
public:

 operator pchar() { return(ConvertToASCII()); }
 MyType& operator=(char* input) { ConvertFromASCII(input); return(*this); }

 pchar ConvertToASCII();
 void ConvertFromASCII(pchar ASCII);
}

Questo tipo di cose è spesso usato nei framework C ++. Ad esempio, dai un'occhiata all'implementazione della classe CString MFC. IMHO, è uno strumento molto utile, sebbene pericoloso in determinate circostanze.

A causa della conversione automatica dei tipi, non è ovvio sapere quale funzione chiamare quando i tipi restituiti sono vicini.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top