2008-10-30 4 views
9

Почему мы не видим C-подобные языки, которые позволяют использовать вызывающие элементы с полиморфизмом в возвращаемом типе? Я мог видеть, как дополнительный вывод типа будет препятствием, но мы имеем plenty of languages с полнофункциональными системами вывода типов (которые работают на разных уровнях «работы»).Полиморфизм возвращаемого типа в языках типа C

Редактировать: Полиморфизм типа возврата Я имею в виду перегрузку сигнатуры функции только в возвращаемом типе. Например, C++ и Java допускают перегрузку только в формальных параметрах, а не в возвращаемом типе.

+0

Тип вывода будет включен в C++ 0x и отличается от полиморфизма возвращаемого типа, который вы предлагаете. – 2008-10-30 08:33:57

ответ

15

Если под «типа полиморфизма возврата» вы имеете в виду перегрузки на основе типа возвращаемого значения, я не уверен, о других языках, но для C++ вот ответ (довольно много из первоисточника):

Функция типы возврата не вступают в игру при разрешении перегрузки просто потому, что Stroustrup (я предполагаю, что с помощью других архитекторов C++) хотел, чтобы разрешение перегрузки было «независимым от контекста». См. 7.4.1 - «Тип перегрузки и возврата» из «Язык программирования C++, третье издание».

Причина заключается в том, чтобы сохранить разрешение на лицо оператора или функции вызова контекстно-независимой.

Они хотели, чтобы он основывался только на том, как была вызвана перегрузка, а не как результат был использован (если он использовался вообще). Действительно, многие функции вызываются без использования результата или результат будет использоваться как часть более крупного выражения. Один из факторов, который, я уверен, вступил в игру, когда они решили, что если бы тип возврата был частью резолюции, было бы много вызовов перегруженных функций, которые нужно было бы разрешить с помощью сложных правил или потребовалось бы, чтобы компилятор ошибка в том, что вызов был неоднозначным.

И, Господь знает, C++ разрешения перегрузки достаточно сложно, поскольку это стоит ...

+0

Правда, любая функция, в которой вы делали это, имела бы неопределенное поведение в контексте void - если не было перегруженного типа возврата void. – cdleary 2008-10-30 05:02:30

3
double x = (double)foo(); 

выше неоднозначен, если есть версии Foo(), которая может возвращать двойную, INT, поплавок и т.д. .

+2

да, но строка s = foo(); double x = foo(); int i = foo(); не являются двусмысленными. Зачем мне возвращать возвращаемый тип foo в double, если foo уже возвратил double? и если никакая версия foo не вернула двойную, то (первый) выбор должен соответствовать перегруженному типу возврата ... – 2008-10-30 06:46:12

0

Из-за автоматического преобразования типов не очевидно, какую функцию вызывать, когда типы возврата близки.

4

Мне бы хотелось увидеть эту функцию на каком-то языке, а не только для того, чтобы функция foo могла возвращать двойной или int или строку, но также и чтобы foo мог возвращать структуру или объекты разных классов. Disambiguating звонки были бы довольно тривиальны - если вызов неоднозначен, для приведения выбранного типа возврата требуется, чтобы выбранный тип возвращался. Пример:

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 

в дополнение

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

эти ситуации не придумали очень часто, но когда они делают обходной путь часто довольно некрасиво ...

+0

в этом случае мы должны запретить не назначенные вызовы или хотя бы что-то вроде (Plant) fooFactory() – shabunc 2013-05-15 14:04:10

2

В C++ вы можете это сделать с классами в значительной степени. Например, скажем, у меня есть тип данных, который обычно конвертируется в ASCII на входе и выходе;

typedef char* pchar; 

class MyType 
{ 
public: 

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

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

Этот тип вещи часто используется в инфраструктурах C++. Например, посмотрите на внедрение класса MFC CString.ИМХО, это очень полезный инструмент, хотя и опасный при определенных обстоятельствах.