Ка правильно написать энумератор по записи...

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

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

Ка правильно написать энумератор по записи...

Сообщение beria » 24.09.2022 11:48:32

Написал для цикла нечто следующее и оно компилируется...
Код: Выделить всё
TDyn = record
    FCurrent: sizeInt;
...........
    class operator Initialize(var aRec: TDyn);
    class operator Finalize(var aRec: TDyn);
    function MoveNext: boolean; inline;
    property Current: sizeInt read FCurrent;
    class operator enumerator(i: sizeInt): TDyn;
  end;     
........
function TDyn.MoveNext: boolean;
begin
  Inc(FCurrent, ItemSize);
  Exit(FCurrent < High);
end;
class operator TDyn.enumerator(i: sizeInt): TDyn;
begin
  Result.FCurrent := -1;
end;



Но в основной программе энумератор не видится
Код: Выделить всё
var
ar2: TDyn;
i: sizeint;
begin
for i in ar2 do Write(' ', i);   /// project1.lpr(129,12) Ошибка: Cannot find an enumerator for the type "TDyn"


Что я не так сделал.. Просто очень мало про энумераторы, применительно к записям вообще есть....
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

Re: Ка правильно написать энумератор по записи...

Сообщение iskander » 24.09.2022 16:38:18

beria писал(а):Написал для цикла нечто следующее и оно компилируется...

Вроде не должно бы оно компилироваться.
Должно быть или так
Код: Выделить всё

TDyn = record
    FCurrent: sizeInt;
...........
    class operator Initialize(var aRec: TDyn);
    class operator Finalize(var aRec: TDyn);
    function GetEnumerator: TDyn;
    function MoveNext: boolean; inline;
    property Current: sizeInt read FCurrent;
  end;
 

или так
Код: Выделить всё
TDyn = record
    FCurrent: sizeInt;
...........
    class operator Initialize(var aRec: TDyn);
    class operator Finalize(var aRec: TDyn);
    function MoveNext: boolean; inline;
    property Current: sizeInt read FCurrent;
  end;
.....
operator Enumerator(var{?} d: TDyn): TDyn;


Кстати использование managed record в качестве энумератора не кажется хорошей идеей, в багтрекере висел связанный с этим баг.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Ка правильно написать энумератор по записи...

Сообщение beria » 24.09.2022 21:57:44

Как минимум ваш первых вариант компилируется до конца, но все равно хрень полная.
Как выяснилось в function TDyn.MoveNext: boolean; не определены (там мусор) любые переменные, TDyn.... Как это - я вот прямо сейчас в шоке. Такое чувство, что при этом неявно создается ещё один экземпляр записи..... Не помню чтобы было в каком-то мануале...

Добавлено спустя 11 часов 7 минут 25 секунд:
Рабочий вариант....
Код: Выделить всё
  function TDyn.GetEnumerator: TDyn;
  begin
    Result:=self;
    Result.FCurrent := -1;
  end;   
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

Re: Ка правильно написать энумератор по записи...

Сообщение iskander » 25.09.2022 16:59:07

beria писал(а):...
Рабочий вариант....

Воля ваша, конечно, но на всякий случай гляньте вот на этот баг.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Ка правильно написать энумератор по записи...

Сообщение beria » 28.09.2022 18:29:59

iskander писал(а):
beria писал(а):...
Рабочий вариант....

Воля ваша, конечно, но на всякий случай гляньте вот на этот баг.


Правится вложенной структурой в записи.
То есть примерно так.. это для энумератора по адресу...

Код: Выделить всё
  TDyn = record
.......
   procedure Z; inline;
    procedure Done;
    class operator Initialize(var aRec: TDyn);
    class operator Finalize(var aRec: TDyn);
  type
    TDynEn = record
      FCurrent: Pointer;
      FinisCurrent: Pointer;
      function MoveNext: boolean; inline;
      property Current: Pointer read FCurrent;
    end;
  var
    En: TDynEn;
    function GetEnumerator: TDynEn; inline;
  end;                                       


И все работает...
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

Re: Ка правильно написать энумератор по записи...

Сообщение iskander » 28.09.2022 18:56:39

Согласен, стало гораздо лучше, но почему энумератор непременно должен быть вложенной структурой?
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Ка правильно написать энумератор по записи...

Сообщение beria » 28.09.2022 19:16:23

iskander писал(а):Согласен, стало гораздо лучше, но почему энумератор непременно должен быть вложенной структурой?

Все очень просто.
Из-за ошибки в FPC, которую никак не правят уже почти год, использование в записи Initialize/Finalize и энумератора просто невозможно одновременно ибо энумератор тоже вызывает Initialize/Finalize и это никак не пресечь. ... ((((( Поэтому и приходится энумератор выносить во внешнюю структуру. Ну в данном случае вложенную ибо так проще...
Но проблема все равно есть - как именно штатными средствами языка из вложенной структуры получить поля корневой.
То есть у нас есть некая функция.....
function TDyn.TDynEn.MoveNext: boolean;
begin
// там изменяется счетчик
end;

Как в этой функции получить не поля TDynEn, а поля TDyn?????
При этом через адрес, то есть грязным образом все работает ибо self = @TDyn.En, а дальше через смещение можно получить любое поле...
TDyn.<имя поля> или просто <имя поля> не проходят компиляцию...
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

Re: Ка правильно написать энумератор по записи...

Сообщение iskander » 28.09.2022 20:17:44

beria писал(а):Ну в данном случае вложенную ибо так проще...

Не только, есть ещё один довод в пользу вложенной структуры: меньше захламляется пространство имён.
beria писал(а):как именно штатными средствами языка из вложенной структуры получить поля корневой.

Экземпляр вложенной структуры должен иметь адрес экземпляра корневой структуры, иначе никак.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

Рейтинг@Mail.ru