Возвращаемый тип полиморфизма в C-подобных языках

StackOverflow https://stackoverflow.com/questions/249296

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

Если по "возвращаемому полиморфизму типа" quot; Вы имеете в виду перегрузку, основанную на типе возвращаемого значения, я не уверен насчет других языков, но для C ++ вот ответ (в значительной степени из уст лошади):

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

  

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

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

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

Другие советы

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

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

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

double x = (double)foo();

Вышеуказанное неоднозначно, если есть версии foo (), которые могут возвращать double, int, float и т. д.

В 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 ++. Например, взгляните на реализацию класса Mtc CString. ИМХО, это очень полезный инструмент, хотя и опасный при определенных обстоятельствах.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top