Ограничение на длинну шаблона?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Ограничение на длинну шаблона?

Сообщение Brainenjii »

Всю голову сломал, пока понял в чем дело... Пишу:

Код: Выделить всё


program Project1;

Type

{ GenericOne }

 Generic GenericOne<T> = Class
  Private
  Public
    Function Hello: T;
End;

Type

{ GenericTwo }

 Generic GenericTwo<T, U> = Class
  Private
  Public
    Function Hello: T;
    Function Dear: U;
End;

Type

{ GenericThree }

 Generic GenericThree<T, U, V> = Class
  Private
  Public
    Function Hello: T;
    Function Dear: U;
    Function World: V;
End;

Type BRequisiteClass = Class
End;
Type BRequisitesList = Specialize GenericOne<BRequisiteClass>;
Type BRequisitesThreadList = Specialize GenericTwo<BRequisiteClass,
  BRequisitesList>;
Type BRequisitesManager = Specialize GenericThree<BRequisiteClass,
  BRequisitesList, BRequisitesThreadList>;

Function GenericThree.Hello: T;
Begin
  Result := T.Create;
End;

Function GenericThree.Dear: U;
Begin
  Result := U.Create;
End;

Function GenericThree.World: V;
Begin
  Result := V.Create;
End;

{ GenericOne }

Function GenericOne.Hello: T;
Begin
  Result := T.Create;
End;

{ GenericTwo }

Function GenericTwo.Hello: T;
Begin
  Result := T.Create;
End;

Function GenericTwo.Dear: U;
Begin
  Result := U.Create;
End;

begin
end.

Не компилируется... Меняем на

Код: Выделить всё

program Project1;

Type

{ GenericOne }

 Generic GenericOne<T> = Class
  Private
  Public
    Function Hello: T;
End;

Type

{ GenericTwo }

 Generic GenericTwo<T, U> = Class
  Private
  Public
    Function Hello: T;
    Function Dear: U;
End;

Type

{ GenericThree }

 Generic GenericThree<T, U, V> = Class
  Private
  Public
    Function Hello: T;
    Function Dear: U;
    Function World: V;
End;

Type BMyClass = Class
End;
Type BMyList = Specialize GenericOne<BMyClass>;
Type BMyThreadList = Specialize GenericTwo<BMyClass, BMyList>;
Type BMyManager = Specialize GenericThree<BMyClass, BMyThreadList, BMyThreadList>;

Function GenericThree.Hello: T;
Begin
  Result := T.Create;
End;

Function GenericThree.Dear: U;
Begin
  Result := U.Create;
End;

Function GenericThree.World: V;
Begin
  Result := V.Create;
End;

{ GenericOne }

Function GenericOne.Hello: T;
Begin
  Result := T.Create;
End;

{ GenericTwo }

Function GenericTwo.Hello: T;
Begin
  Result := T.Create;
End;

Function GenericTwo.Dear: U;
Begin
  Result := U.Create;
End;

begin
end.

Компилируется!!!!! Как быть? ^_^
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

Что с этим можно сделать? >_<
Я искренне полюбил Generic'и, но это ограничение просто убивает. В выходные поработал дома (x86_64) - всё собралось нормально, прихожу на работу (x86_32):
/home/Brainenjii/Develop/BStore/trunk/./Peas/Controllers/bbasereqpatternscontrollerunit.pas:127: undefined reference to `VMT_BBASEREQPATTERNSCONTROLLERUNIT_BCONTROLLERGENERIC$BBASEREQPATTERNCLASS$BBASEREQPATTERNSMANAGERCLASS_$__BTHREADLIST$BBASEREQPATTERNCLA'
Error: Error while linking

а я люблю длинные назвния >_<
В общем, есть какой-нибудь способ обойти это?
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

Буквально на днях в транке что-то поменяли на эту тему. У меня свежим транком компилируется (win32). А вот 2.6.0 выдает ошибку.
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

http://bugs.freepascal.org/view.php?id=20663 - ооо! Мой жеж баг :-D но, блин, страчно как-то...
Есть жизнь на 2.7.1? Кто-нибудь пользует в рабочих проектах?

Добавлено спустя 36 минут 57 секунд:
и ещё, проверьте, пожалуйста, два проекта:
первый из трёх модулей:
  • Program:

    Код: Выделить всё

    program Project1;

    {$mode objfpc}{$H+}

    uses
      fgl, Unit1, Unit2;

    Type TMyFirst = Specialize TFirst<TMyClass>;

    Var
      aMyList: TMyList;
      aMyFirst: TMyFirst;

    { TFirst }

    begin
      aMyList := TMyList.Create;
      aMyFirst := TMyFirst.Create;
      aMyFirst.Load(aMyList);
      aMyList.Free;
      aMyFirst.Free;
    end.
  • Unit1:

    Код: Выделить всё

    Unit Unit1; 

    {$mode objfpc}{$H+}

    Interface

    Uses
      fgl;

    Type TMyClass = Class
    End;

    Type TMyList = Specialize TFPGList<TMyClass>;

    Implementation

    End.
  • Unit2:

    Код: Выделить всё

    Unit Unit2; 

    {$mode objfpc}{$H+}

    Interface

    Uses
      fgl;

    Type

    { TFirst }

     Generic TFirst<T> = Class
      Type TManagedList = Specialize TFPGList<T>;
      Public
        Procedure Load(Const aList: TManagedList);
    End;

    Implementation

    Procedure TFirst.Load(Const aList: TManagedList);
    Begin

    End;

    End.
Это не собирается. Но если вынести содержимое Unit1 в Program - всё соберётся
  • Program:

    Код: Выделить всё


    program Project1;

    {$mode objfpc}{$H+}

    uses
      fgl, Unit1, Unit2;

    Type TMyClass = Class
    End;

    Type TMyList = Specialize TFPGList<TMyClass>;

    Type TMyFirst = Specialize TFirst<TMyClass>;

    Var
      aMyList: TMyList;
      aMyFirst: TMyFirst;

    { TFirst }

    begin
      aMyList := TMyList.Create;
      aMyFirst := TMyFirst.Create;
      aMyFirst.Load(aMyList);
      aMyList.Free;
      aMyFirst.Free;
    end.
  • Unit1 (можно убрать):

    Код: Выделить всё

    Unit Unit1; 

    {$mode objfpc}{$H+}

    Interface

    Implementation

    End.
  • Unit2 - без изменений

    Код: Выделить всё

    Unit Unit2; 

    {$mode objfpc}{$H+}

    Interface

    Uses
      fgl;

    Type

    { TFirst }

    Generic TFirst<T> = Class
      Type TManagedList = Specialize TFPGList<T>;
      Public
        Procedure Load(Const aList: TManagedList);
    End;

    Implementation

    Procedure TFirst.Load(Const aList: TManagedList);
    Begin

    End;

    End.
Если в 2.7.1 первый проект собёрется - значит там сильно круче ^_^
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

generictest11.lpr(19,24) Error: Incompatible type for arg no. 1: Got "T11U1.TFPGList$1$TMyClass", expected "GENERICTEST11.TFPGList$1$TMyClass"
generictest11.lpr(17,15) Hint: Found declaration: TFirst$1$TMyClass.Load(const TFPGList$1$TMyClass);

Пакостный баг недавно тоже на него натолкнулся.

Добавлено спустя 1 минуту 47 секунд:
В 2.6.0 те же яйца только сбоку
generictest11.lpr(19,24) Error: Incompatible type for arg no. 1: Got "TFPGList$TMyClass", expected "TFirst$TMyClass.TFPGList$TMyClass"
generictest11.lpr(17,15) Hint: Found declaration: TFirst$TMyClass.Load(const TFPGList$TMyClass);
Ответить