如果有多个候选人,是否有规则选择重载例程?

时间:2015-06-21 20:08:40

标签: delphi generics overloading

我试图欺骗编译器从多个可用选项中选择特定的重载方法。

如果编译器选择带泛型参数的方法,它将始终通过引用传递,但出于内联原因,我更喜欢通过值传递参数。

但是我很难找到一个明确的规则来确定编译器如何选择要调用的重载方法。

请考虑以下代码:

program Project45;
{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TX = type byte;

  TTest<T> = class
    class function Compare(const a,b: T): shortstring; overload; static; inline;
    class function Compare(const a,b: integer): shortstring; overload; static; inline;
    class function Compare(const a,b: cardinal): shortstring; overload; static; inline;
    class function Compare(const a,b: shortint): shortstring; overload; static; inline;
    class function Compare(const a,b: byte): shortstring; overload; static; inline;
    class function Compare(const a,b: smallint): shortstring; overload; static; inline;
    //class function Compare(const a,b: T): shortstring; overload; static; inline;
  private
  end;

class function TTest<T>.Compare(const a, b: integer): shortstring;
begin
  Result:= 'Integer compare';
end;

class function TTest<T>.Compare(const a, b: byte): shortstring;
begin
  Result:= 'Byte compare';
end;

class function TTest<T>.Compare(const a, b: smallint): shortstring;
begin
  Result:= 'Smallint compare';
end;


class function TTest<T>.Compare(const a, b: int8): shortstring;
begin
  Result:= 'Shortint Compare';
end;

class function TTest<T>.Compare(const a, b: cardinal): shortstring;
begin
  Result:= 'Cardinal compare';
end;

class function TTest<T>.Compare(const A,B: T): shortstring;
begin
  Result:= 'Generic compare';
end;

function test: boolean;
var
  A,B: byte;
  c,d: shortint;
  w1,w2: word;
  e,f: TX;
begin
  a:= 1; b:= 255;
  c:= 1; d:= -1;
  e:= 1; f:= 255;
  WriteLn('TTest<byte>.Compare(byte)'+#9+(TTest<byte>.Compare(a, b)));
  WriteLn('TTest<shortint>.Compare(byte)'+#9+(TTest<shortint>.Compare(a, b)));
  WriteLn('TTest<byte>.Compare(shortint)'+#9+(TTest<byte>.Compare(c, d)));
  WriteLn('TTest<shortint>.Compare(shortint)'+#9+(TTest<shortint>.Compare(c, d)));
  WriteLn('TTest<smallint>.Compare(word)'+#9+(TTest<smallint>.Compare(w1, w2)));
  WriteLn('TTest<smallint>.Compare(smallint)'+#9+(TTest<smallint>.Compare(smallint(w1), smallint(w2))));
  WriteLn('TTest<shortint>.Compare(tx)'+#9+#9+(TTest<shortint>.Compare(e, f)));
  WriteLn('TTest<TX>.Compare(tx)'+#9+#9+(TTest<TX>.Compare(e, f)));
  ReadLn;
end;

begin
  Test;
end.

如果我将泛型方法放在类中,则输出以下内容:

TTest<byte>.Compare(byte)   ->            Generic compare  
TTest<shortint>.Compare(byte) ->          Byte compare  
TTest<byte>.Compare(shortint) ->          Shortint Compare  
TTest<shortint>.Compare(shortint)  ->     Generic compare   
TTest<smallint>.Compare(word) ->          Integer compare  
TTest<smallint>.Compare(smallint)  ->     Generic compare  
TTest<shortint>.Compare(tx)       ->      Byte compare  
TTest<TX>.Compare(tx)      ->             Generic compare  

如果我将泛型方法放在最后,输出将更改为:

TTest<byte>.Compare(byte)    ->           Byte compare  
TTest<shortint>.Compare(byte) ->          Byte compare  
TTest<byte>.Compare(shortint) ->          Shortint Compare  
TTest<shortint>.Compare(shortint) ->      Shortint Compare  
TTest<smallint>.Compare(word) ->          Integer compare  
TTest<smallint>.Compare(smallint)  ->     Smallint compare  
TTest<shortint>.Compare(tx)     ->        Byte compare  
TTest<TX>.Compare(tx)      ->             Generic compare  

第一个有一个非常随机的感觉,第二个更有意义,但有时更改类型参数会使编译器更改其调用,有时更改参数本身会影响更改。

编译器使用什么规则来选择要调用的重载方法?

0 个答案:

没有答案