Вопрос перегрузки функций в Delphi может быть довольно запутанным, особенно когда речь заходит о преобразовании типов. Вопрошающий столкнулся с ситуацией, когда компилятор Delphi выбирал перегруженный параметр типа UInt64 вместо пользовательского типа MyWord, несмотря на наличие явного преобразования из LongWord в MyWord.
Контекст проблемы
Рассмотрим код программы, который демонстрирует проблему:
program Promote;
{$APPTYPE CONSOLE}
uses
SysUtils;
{$HINTS OFF}
type
MyWord = record
FValue: LongWord;
class operator Implicit(AValue: LongWord): MyWord;
end;
class operator MyWord.Implicit(AValue: LongWord): MyWord;
begin
Result.FValue:= AValue;
end;
procedure Test(AValue: MyWord); overload;
begin
Writeln('MyWord');
end;
procedure Test(AValue: UInt64); overload;
begin
Writeln('UInt64');
end;
var
LW: LongWord;
begin
Test(LW); // Вызывается Test(AValue: UInt64);
Readln;
end.
При выполнении этой программы в Delphi XE компилятор выбирает перегрузку для UInt64, несмотря на наличие явного преобразования из LongWord в MyWord. Вопрошающий задаёт вопрос о том, всегда ли компилятор предпочитает встроенные типы для преобразования, и какие правила управляют этим процессом в общем случае.
Подтвержденный ответ
Исходя из наблюдений и экспериментов, можно сделать следующие выводы:
Компилятор Delphi предпочитает встроенные типы для преобразования перед пользовательскими типами.
При сравнении двух встроенных типов компилятор следует документации, но стоит отметить, что документация может быть неточной.
Если у нас есть два пользовательских типа, доступных через операторы явного преобразования, это считается неоднозначностью.
Если у нас есть один встроенный тип и один пользовательский, предпочтение отдаётся встроенному типу.
Компилятор в первую очередь выбирает процедуру, которая сохраняет значения фактических параметров.
В случае, если несколько процедур удовлетворяют первому условию, компилятор предпочитает знаковые типы неопределённой длины перед беззнаковыми.
Альтернативный ответ
Существует мнение, что упорядоченные типы, такие как uint64 и longword, всегда будут ближе друг к другу, чем к записям. Это означает, что "близость" типов не зависит от того, являются ли они встроенными или пользовательскими. Как только определяется запись, она будет аффинирована с другими записями, а не с упорядоченными типами.
Заключение
Понимание правил перегрузки функций в Delphi требует не только знания о доступных перегрузках, но и учета поведения компилятора при выборе наиболее подходящего типа для преобразования. Несмотря на недостаточную документированность, разработчики могут ориентироваться на общие принципы и экспериментальные наблюдения для лучшего понимания того, как компилятор принимает решения в таких ситуациях.
заключается в том, что при перегрузке функций в Delphi компилятор может выбирать перегруженный параметр типа `UInt64` вместо пользовательского типа `MyWord` даже при наличии явного преобразования, что вызвано определенными правилами выб
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS