Модератор: Модераторы
shade писал(а):Мне вот, что интересно. Эти женерики будут плодить шаблонные копии как в С++....
hp:=tdef(tobjectdef(ttypesym(p).typedef).symtable.DefList[i]);
if hp.typ=procdef then
  begin
     if assigned(tprocdef(hp).genericdef) and
     (tprocdef(hp).genericdef.typ=procdef) and
      assigned(tprocdef(tprocdef(hp).genericdef).generictokenbuf) then
      begin
         oldcurrent_filepos:=current_filepos;
          current_filepos:=tprocdef(tprocdef(hp).genericdef).fileinfo;
          current_tokenpos:=current_filepos;
          current_scanner.startreplaytokens
             (tprocdef(tprocdef(hp).genericdef).generictokenbuf);
          read_proc_body(nil,tprocdef(hp)); // <--- !!!! 
// Parses the procedure directives, then parses the procedure body, then
// generates the code for it(комментарий на read_proc_body)
           current_filepos:=oldcurrent_filepos;
       endshade писал(а):Мне вот, что интересно. Эти женерики будут плодить шаблонные копии как в С++ или все таки намудрили как-нибудь так, чтобы была лишь одна версия кода за которой скрываются неявные преобразования TObject <-> Pointer??
shade писал(а):, чтобы была лишь одна версия кода за которой скрываются неявные преобразования TObject <-> Pointer??
zub писал(а):если такое преобразование возможно, то это решается правильной архитектурой наследования типов а не генериками. генерики какраз для типов которые которые привести друг к другу нельзя
template <class TObj>
function min(A, B: TObj): TObj;
begin
  if A.CompareTo(B) < 0 then Result := A
  else Result := B;
end;
var A, B, C: TSomeObj;
C := min(A, B);
min_TObj = interface
  function CompareTo(X: min_TObj): Integer;
end;function min(A, B: min_TObj): min_TObj;
begin
  if A.CompareTo(B) < 0 then Result := A
  else Result := B;
end;var A, B, C: TSomeObj;
C := TSomeObj( GetObjectFromIntrf( min(A as min_TObj, B as min_TObj) ) );
zub писал(а):непонял к чему тут интерфейсы?
все вышесказанное применимо только к class`ам. как быть с простыми типами?
function Integer_CompareTo(var A, B: Integer): Integer;
begin
  Result := A - B;
end;
type
  TemplateIntrfRec = record
    VMT: Pointer;
    Obj: Pointer;
  end;
var min_IntegerVMT: array [0..0] of Pointer = (@Integer_CompareTo);
function IntegerAsTemplateIntrf(var X: Integer): TemplateIntrfRec; inline;
begin
  Result.VMT := @min_IntegerVMT;
  Result.Obj := @X;
end;
function GetObjectFromIntrf(var TI: TemplateIntrfRec): Pointer; inline;
begin
  Result := TI.Obj;
end;
var A, B, C: Integer;
C := PInteger( GetObjectFromIntrf(min(IntegerAsTemplateIntrf(A), IntegerAsTemplateIntrf(B))) )^;
shade писал(а):В принципе не вижу пользы от примения шаблонов к простым типам, но если очень нужно, то компилятор может применить "шаблонный интерфейс" и к простому типу
Это то, что должен делать компилятор на основе обычного описания женерика/шаблона.zub писал(а):это всё хаки...
процедура тип_CompareTo - это метод класса, поставляемого в шаблон он один единственный для каждого класса.zub писал(а):к томуже процедур тип_CompareTo получится столькоже сколько типов. чем это лучше создания генериком своих проуедур для каждого типа?
template <class TSomeType>
TSomeType min(TSomeType A, TSomeType B)
{
 if ( A.CompareTo(B) > 0 ) return A; else return B; }
class TObj1 { int a;
 TObj1(int X): a(X) {}
 int CompareTo(TObj X) { return a - X.a; } 
};
class TObj2 {
 float a;
 TObj2(float X): a (X) {}
 int CompareTo(TObj X) { return int(a - X.a); }
 };
void test()
{
  min(TObj1(5), TObj2(80));
  min(TObj2(1.2), TObj2(0.7));
}Вернуться в Free Pascal Compiler
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1