[fpc-pascal] Re: generics question

Adrian Veith adrian at veith-system.de
Sat May 14 12:14:10 CEST 2011


But is very strange, that this works:

type
  TTestGen<T> = class
    constructor Create();
    class function Test(val: T): string; inline;
  end;


function Blah(const val: Integer): string; inline; //overload;
begin
  Result:= IntToStr(val + 1);
end;

{function Blah(const val: string): string; inline; overload;
begin
  Result:= val + '1';
end;
}

{ TTestGen }

constructor TTestGen<T>.Create();
begin
end;

class function TTestGen<T>.Test(val: T): string;
begin
  Result:= Blah(val);
end;

type
  TTestInt = TTestGen<Integer>;
  //TTestString = TTestGen<String>;

begin
  writeln(TTestInt.Test(2));
  //writeln(TTestString.Test('2'));
  readln;
end.

T is also not yet known. Why does it not work with overloaded functions
? IMHO this is not consequent.

Cheers,

Adrian.

On 14.05.2011 11:09, leledumbo wrote:
> Err... because at the time, T is not yet known. It would still fail to
> compile even if you don't do any specialization. I guess the compiler does
> type checking while parsing the generic class (and its methods) declaration,
> not while specializing (well... it would still do type checking when
> specializing, but the error would be a little cryptic due to missing exact
> error location).
>
> IMHO a solution would be to have additional compile-time syntax to check the
> type of T (but this may cause a lot of headache due to inheritance concept).
> Since it's impossible with the current state, the current solution would be
> to declare a procedural type (with T as argument) inside the generic class
> and instead of calling blah directly make it a procedural variable of that
> type as argument of Test (since it's a class function). The caveat is of
> course you have to pass Blah all the time. But unfortunately... it doesn't
> work as well :(
>
> Here's your modified program (compiled, but just run and see its output):
>
> {$mode delphi}
>
> uses
>   SysUtils;
>
>
> function Blah(const val: Integer): string; inline; overload;
> begin
>   Result:= IntToStr(val + 1);
> end;
>
> function Blah(const val: string): string; inline; overload;
> begin
>   Result:= val + '1';
> end;
>
> type
>   TTestGen<T> = class
>   type
>     TBlah = function (const val: T): string;
>   public
>     constructor Create();
>     class function Test(val: T; ABlah: TBlah): string; inline;
>   end;
>
> { TTestGen }
>
> constructor TTestGen<T>.Create();
> begin
> end;
>
> class function TTestGen<T>.Test(val: T; ABlah: TBlah): string;
> begin
>   Result:= ABlah(val);
> end;
>
>
> type
>   TTestInt = TTestGen<Integer>;
>   TTestString = TTestGen<String>;
>
> begin
>   WriteLn(TTestInt.Test(1, at Blah));
>   WriteLn(TTestString.Test('test', at Blah));
> end.
>
> If I don't overload Blah and pass the correct function for each call, then
> the result is correct. Somebody's gotta file a bug report.
>
> --
> View this message in context: http://free-pascal-general.1045716.n5.nabble.com/generics-question-tp4389896p4395332.html
> Sent from the Free Pascal - General mailing list archive at Nabble.com.
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal



More information about the fpc-pascal mailing list