Шаблоны С++ vs Generic free pascal

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

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

Mike81
незнакомец
Сообщения: 9
Зарегистрирован: 20.02.2012 14:11:36

Шаблоны С++ vs Generic free pascal

Сообщение Mike81 »

В с++ имеется пример шаблона

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

template< int T >
class IntegerArray
{
  int Arr[ T ];
  /* ... */
};

по анологии с шаблоном в free pascal можно использовать generic
Как я понял- это выглядит так

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

 {$mode objfpc}

.....
generic IntegerArray<T> = object
......

однако проблема в том, что T- в данном случае не типизирован как в примере с с++.
То есть T нельзя использовать как величину определяющую верхнюю границу массива, как в предыдущем примере.

Вопрос, можно ли типизировать параметр generic-a или нет?

Впринципе есть такое "не элегантное" решение этого вопроса для аналога выше приведенного примера:

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

type
generic IntegerArray<T> = object
Arr: array[0..sizeof(T)] of integer;
//....
end;

где потом
можно так- для случая T=10

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

type
Tt=array[1..10] of byte;

var
x : specialize IntegerArray<Tt>;
.....

Может все таки есть что-то более стандартное?
Последний раз редактировалось Mike81 21.03.2012 00:13:52, всего редактировалось 1 раз.
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

В 2.7.1 должно сработать так, хотя и не так удобно как в С++.

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

generic IntegerArray<TSize> = object
Arr: array[0..TSize.Size-1] of Integer;
end;

TSize10 = class
public
  const Size = 10;
end;

TArr = specialize IntegerArray<TSize10>;
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

По идее, стандартным решением должно быть такое:

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

type
  generic IntegerArray<T>=object
    arr: array[T] of Integer;
  end;

  TRange=1..10;

  TArr=specialize IntegerArray<TRange>;

однако ж нифига не работает.
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

Но должно. Исправляли же уже это. http://bugs.freepascal.org/view.php?id=20028
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Твой пример (с константой в классе) работает. Мой (с диапазоном) - нет.
alexey38
долгожитель
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Сообщение alexey38 »

Чисто из любопытства, а для каких целей и задач требуется именно такое использование? Чем плохи динамические массивы и шаблоны для работы с ними, с инициализацией размерности в конструкторе?
Мой вопрос не про возможности компилятора, а про подходы к программированию.
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

Статический массив быстрее.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

AlexVinS
А просто в классическом стиле объявить массив уже не кошерно?
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

От задачи зависит. Например matrix из rtl переписанный на дженерики выглядел бы гораздо лучше.
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

AlexVinS писал(а):Статический массив быстрее.
А как со скоростью компиляции и потребляемой при этом памятью? Не хотелось бы по этим показателям догнать плюсы.
alexey38
долгожитель
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Сообщение alexey38 »

AlexVinS писал(а):Статический массив быстрее.


А в чем быстрее? Статический массив один и выделяется в памяти в момент запуска программы. Выделение памяти под динамический массив работает не намного дольше, особенно если массив один. Выигрыш ничтожный по времени.

А после выделения динамического массива работа с элементами, насколько я понимаю, ни чем не отличается от работы со статическим массивом. При необходимости можно использовать процедуры, заточенные под статические массивы.
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

alexey38 писал(а):
AlexVinS писал(а):Статический массив быстрее.


А в чем быстрее? Статический массив один и выделяется в памяти в момент запуска программы. Выделение памяти под динамический массив работает не намного дольше, особенно если массив один. Выигрыш ничтожный по времени.



Это смотря где он находится, ом может быть в сегменте данных (если это просто переменная в модуле) - память выделяется сразу при запуске приложения на весь сегмент данных, в стеке, если он в локальной переменной в функции (возможно внутри object) - память выделяется просто в стеке - это очень быстро по сравнению с кучей, или в куче в составе объекта (память выделяется один раз под весь объект). А если массив динамический то он в отдельном блоке кучи всегда.

alexey38 писал(а):
AlexVinS писал(а):Статический массив быстрее.


А после выделения динамического массива работа с элементами, насколько я понимаю, ни чем не отличается от работы со статическим массивом. При необходимости можно использовать процедуры, заточенные под статические массивы.


При работе с элементами, конечно, никакой разницы уже нет.
alexey38
долгожитель
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Сообщение alexey38 »

Вопрос, а класс разве может выделяться в стеке? Насколько я помню, он всегда выделяется в куче.

А если все же быстродействие, связанное с выделением памяти критичное для конкретной задачи, то почему бы в данном случае просто не отказаться от генериков. Чуточку вырастит код.
Я в немного похожих задачах в свое время в классе использовал указатель на память, как статический массив. А выделение памяти (статически или динамически) отдельным оператором. Собственно код был универсален. пара лишних строк кода в программе. Но конкретно мне генерики и не могли помочь, т.к. у меня массив выделялся через FileMapping для межпроцессного обмена.

Понятно, что вроде бы как ограничение языка. Но с другой стороны, все равно на всех не угодишь. В любой задаче можно найти фичи, которые конкретный язык делает не оптимально. А сверхгибкость - это источник проблем с надежностью и прозрачностью кода.
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

Mike81 писал(а):В с++ имеется пример шаблона

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

template< int T >
class IntegerArray
{
  int Arr[ T ];
  /* ... */
};

по анологии с шаблоном в free pascal можно использовать generic
.....
Может все таки есть что-то более стандартное?


Совсем стандартное (работает хоть в FPC 2.0.2 или D3):

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

type
_GenericType = array[1..10] of byte;
{$I template.inc}
TIntegerArray = _GenericArray;
------ template.inc -------
_GenericArray = object
Arr: array[0..sizeof(GenericType)] of integer;
//....
end;


Параметризовать можно чем угодно - типами, функциями, константами. Куда ближе к темплейтам, чем дженерики.
По-моему в примере шаблона он скорее константой параметризуется.
dedm0zaj
постоялец
Сообщения: 108
Зарегистрирован: 05.10.2012 19:55:20

Сообщение dedm0zaj »

AlexVinS писал(а):Статический массив быстрее.

по моим тестам дин массивы так же быстры, как и статические (чтение и запись)
Ответить