2008-10-30 19 views
9

Dlaczego nie widzimy języków podobnych do C, które pozwalają na wywoływanie z polimorfizmem w typie zwrotnym? Mogłem zobaczyć, jak dodatkowe wnioskowanie typu byłoby przeszkodą, ale mamy plenty of languages z pełnoprawnymi systemami wnioskowania typu (które działają na różnych poziomach "pracy").Polimorfizm typu zwrotnego w językach typu C

Edytuj: Przez polimorfizm typu zwrotu rozumiem przeciążanie sygnatury funkcji tylko w typie zwracanym. Na przykład C++ i Java zezwalają tylko na przeciążanie w typie parametrów formalnych, a nie w typie zwracanym.

+0

Typ wnioskowania będą zawarte w C++ 0x i różni się od sugerowanego polimorfizmu typu powrotu. –

Odpowiedz

15

Jeśli przez „polimorfizmu typu Return” masz na myśli przeciążeń na podstawie typu wartości powrotu, nie jestem pewien o innych językach, ale dla C++ oto odpowiedź (dość dużo z pierwszej ręki):

Function typy powrotu nie wchodzą w grę w rozdzielczości przeciążania tylko dlatego, że Stroustrup (zakładam przy pomocy danych od innych architektów C++) chciał, aby rozdzielczość była zbyt niezależna od kontekstu. Zobacz 7.4.1 - "Przeciążanie i typ zwracania" z "Języka programowania w C++, wydanie trzecie".

Powodem jest to, aby zachować rozdzielczość dla jednostka operator lub funkcja wezwanie kontekst niezależne.

Chcieli, aby opierał się on tylko na tym, jak nazywano przeciążenie - nie w jaki sposób użyto wyniku (jeśli w ogóle był używany). Rzeczywiście wiele funkcji wywoływanych jest bez użycia wyniku, a wynik może być użyty jako część większego wyrażenia. Jeden czynnik, który jestem pewny, wszedł w grę, gdy zdecydowali, że to, że jeśli typ powrotu był częścią rozdzielczości, byłoby wiele wezwań do przeciążenia funkcji, które wymagałyby rozwiązania za pomocą złożonych reguł lub musiałoby mieć rzut kompilatora błąd, który wywołanie było niejednoznaczne.

A Pan wie, rozdzielczość przeciążenie C++ jest na tyle skomplikowane, gdyż stoi ...

+0

Prawda, każda funkcja, w której to zrobiłbyś, miała niezdefiniowane zachowanie w pustym kontekście - chyba że wystąpił przeciążony typ zwracanej pustki. – cdleary

3
double x = (double)foo(); 

Powyższe jest niejednoznaczny, jeżeli istnieją wersje Foo(), która może powrócić double, int, float, etc

+2

tak, ale ciąg s = foo(); podwójne x = foo(); int i = foo(); nie są niejednoznaczne. Dlaczego miałbym rzucić zwrotny typ foo, aby podwoić, jeśli foo już zwrócił podwójne? a jeśli żadna wersja foo nie zwróci podwójnego, wówczas (pierwszy) rzut powinien pasować do przeciążonego typu zwrotu ... –

0

Ze względu na automatyczną konwersję typów nie jest oczywiste, aby wiedzieć, którą funkcję wywołać, gdy typy zwrotu są blisko.

4

Chciałbym zobaczyć tę funkcję w pewnym języku, nie tylko po to, aby funkcja foo mogła zwrócić wartość double lub int lub string, ale także aby foo mogło zwrócić strukturę lub obiekty różnych klas. Rozróżnianie wywołań byłoby dość banalne - jeśli wywołanie jest niejednoznaczne, wymaga rzutowania, aby wybrać żądany typ zwrotu. Przykład:

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 

oprócz

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

sytuacje te nie pojawią się bardzo często, ale gdy robią obejście problemu jest często dość brzydki ...

+0

w takim przypadku powinniśmy zakazywać nieprzypisane połączenia lub przynajmniej mieć coś takiego jak (Plant) fooFactory() – shabunc

2

w C++ można to zrobić z klasami w dużym stopniu. Na przykład powiedzmy, że mam typ danych, który jest rutynowo konwertowany na ASCII na wejściu i wyjściu;

typedef char* pchar; 

class MyType 
{ 
public: 

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

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

Tego typu rzeczy są często używane w frameworkach C++. Na przykład spójrz na implemetację klasy MFC CString.IMHO, to bardzo przydatne narzędzie, aczkolwiek niebezpieczne w pewnych okolicznościach.