Модератор: Модераторы
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;
end
shade писал(а):Мне вот, что интересно. Эти женерики будут плодить шаблонные копии как в С++ или все таки намудрили как-нибудь так, чтобы была лишь одна версия кода за которой скрываются неявные преобразования 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
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6