2008-10-30 18 views
9

¿Por qué no vemos lenguajes en forma de C que permitan que los callables tengan polimorfismo en el tipo de retorno? Pude ver cómo la inferencia de tipo adicional sería un obstáculo, pero tenemos plenty of languages con sistemas de inferencia de tipo completo (que funcionan para diferentes niveles de "trabajo").Polimorfismo del tipo de retorno en las lenguas C-like

Editar: Por polimorfismo de tipo de retorno me refiero a sobrecargar la firma de la función solo en el tipo de devolución. Por ejemplo, C++ y Java solo permiten la sobrecarga en el tipo de parámetros formales, no en el tipo de devolución.

+0

La inferencia de tipo se incluirá en C++ 0x, y es diferente del polimorfismo de tipo de retorno que está sugiriendo. –

Respuesta

15

Si por "tipo de polimorfismo de retorno" te refieres a la sobrecarga en base al tipo de valor de retorno, no estoy seguro acerca de otros idiomas, pero para C++ Aquí está la respuesta (más o menos de la boca del caballo):

Función Los tipos de retorno no entran en juego en la resolución de sobrecarga simplemente porque Stroustrup (supongo que con la contribución de otros arquitectos de C++) quería que la resolución de sobrecarga fuera 'independiente del contexto'. Consulte 7.4.1 - "Tipo de sobrecarga y retorno" del "Lenguaje de programación C++, tercera edición".

La razón es mantener la resolución de un operador o función individual llamada independiente del contexto.

Querían que se basara solo en cómo se llamaba la sobrecarga, no cómo se usaba el resultado (si se utilizó en absoluto). De hecho, muchas funciones se llaman sin usar el resultado o el resultado se usaría como parte de una expresión más grande. Un factor que estoy seguro entró en juego cuando decidieron esto era que si el tipo de devolución formaba parte de la resolución habría muchas llamadas a funciones sobrecargadas que tendrían que resolverse con reglas complejas o tendrían que tener el lanzamiento del compilador un error que la llamada fue ambigua.

Y, Señor sabe, C++ resolución de sobrecarga es lo suficientemente complejo, ya que se encuentra ...

+0

Es cierto que cualquier función en la que hiciera esto tendría un comportamiento indefinido en un contexto vacío, a menos que hubiera un tipo de retorno void sobrecargado. – cdleary

3
double x = (double)foo(); 

Lo anterior es ambigua si hay versiones de foo() que puede devolver el doble, int, float, etc.

+2

sí pero cadena s = foo(); doble x = foo(); int i = foo(); no son ambiguos ¿Por qué debería convertir el tipo de retorno de foo a double si foo ya devolvió un doble? y si ninguna versión de foo devolvió un doble, entonces el (primer) elenco debería coincidir con el tipo de retorno sobrecargado ... –

0

Debido a la conversión automática de tipos, no es obvio saber a qué función llamar cuando los tipos de devolución están cerca.

4

Me encantaría ver esta característica en algún idioma, no solo para que la función foo pueda devolver un doble o un int o una cadena, sino también para que foo pueda devolver una estructura u objetos de diferentes clases. La desambiguación de las llamadas sería bastante trivial: si la llamada es ambigua, se requiere un molde para seleccionar el tipo de retorno deseado. Ejemplo:

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 

además

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

estas situaciones no vienen muy a menudo, pero cuando lo hacen la solución es a menudo bastante fea ...

+0

en ese caso deberíamos prohibir las llamadas no asignadas o al menos tener algo así como (Planta) fooFactory() – shabunc

2

En C++ se puede hacer esto con clases en gran medida. Por ejemplo, supongamos que tengo un tipo de datos que se convierte rutinariamente a ASCII en entrada y salida;

typedef char* pchar; 

class MyType 
{ 
public: 

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

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

Este tipo de cosas se utiliza a menudo en los frameworks de C++. Por ejemplo, eche un vistazo a la implementación de la clase MFC CString.En mi humilde opinión, es una herramienta muy útil, aunque peligrosa en ciertas circunstancias.

Cuestiones relacionadas