powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Generics, а собственно как сравнить элементы <T> ?
25 сообщений из 49, страница 1 из 2
Generics, а собственно как сравнить элементы <T> ?
    #40032918
Страдалецъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делаю простенькую штуку и получаю ошибку компиляции:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
TRange<T> = record
  private
    FMin, FMax: T;
  public
    function Contains(Value: T): Boolean;
  end;
...
function TRange<T>.Contains(Value: T): Boolean;
begin
 Result := (Value >= FMin) and (Value <= FMax) //E2015 Operator not applicable to this operand type
end;


И как это правильно сделать?
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032924
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ
И как это правильно сделать?

В Delphi - через боль и страдание. В FPC - легко и просто.
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032925
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ,

Посмотри что-то типа TComparer<T>.Default
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032926
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Можно поподробней?
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032927
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU,

Подробнее о боли или о лёгкости?
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032928
Страдалецъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПосмотри что-то типа TComparer<T>.Default
Действительно боль, проще с вариантами сделать.
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032930
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU,

До твоего комментария я думал, что в FPC как раз всё печально )
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032931
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ,

пробуй так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
class function TArrHelper<T>.IndexOf(var Arr: TArray<T>; const Item: T): integer;
var
 i: integer;
begin
 Result := -1;
 for i := 0 to High(Arr) do
  if TComparer<T>.Default.Compare(Arr[i], Item) = 0 then
   Exit(i);
end;
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032932
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU
До твоего комментария я думал, что в FPC как раз всё печально )

В FPC всё естественно, без компареров, тайпкайндов и прочего дельфийского секса. Обсуждалось уже, читать можно, примерно, отсюда .
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032933
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Пробежался, так и не понял
Как на FPC решить вопрос ТС?
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032934
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOU
Как на FPC решить вопрос ТС?

Да вот как у него код написан, так и решить.
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032946
Страдалецъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забил я на дженерики, сделал через вариант:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
  TRange = record
  private
    FMin, FMax: Variant;
  public
    constructor Create(MinValue, MaxValue: Variant);
    function Contains(Value: Variant): Boolean;
    function Random: Variant;
  end;

function TRange.Contains(Value: Variant): Boolean;
begin
 Result := False;
 case VarType(Value) of
  varSmallInt,varInteger,varShortInt..varUInt64,varSingle..varCurrency:
    Result := (Value >= FMin) and (Value <= FMax);
  varDate: if Value < 1
    then Result := (Int(FMin) + Value >= FMin) and (Int(FMin) + Value <= FMax)
    else Result := (Value >= FMin) and (Value <= FMax);
 end;
end;

constructor TRange.Create(MinValue, MaxValue: Variant);
begin
 FMin := MinValue;
 FMax := MaxValue;
end;

function TRange.Random: Variant;
begin
 Result := 0;
 case VarType(FMin) of
  varSmallInt,varInteger,varShortInt..varUInt64:
    Result := FMin + System.Random(FMax);
  varSingle..varCurrency:
    Result := FMin + System.Random * (FMax - FMin);
  varDate: if FMin < 1
    then Result := FMin + System.Random * (FMax - FMin)
    else if Frac(FMin) = 0
         then Result := FMin + Int(System.Random * (FMax - FMin))
         else Result := FMin + System.Random * (FMax - FMin);
 end;
end;


Использование:
Код: pascal
1.
2.
3.
4.
5.
 Memo1.Lines.Add(TRange.Create(1, 100).Random);
 Memo1.Lines.Add(TRange.Create(0.1, 9.1).Random);
 Memo1.Lines.Add(TRange.Create(StrToDate('01.01.2021'), StrToDate('10.01.2021')).Random);
 Memo1.Lines.Add(TRange.Create(StrToTime('00:00'), StrToTime('23:59')).Random);
 Memo1.Lines.Add(TRange.Create(StrToDateTime('01.01.2021 00:01'), StrToDateTime('10.01.2021 23:59')).Random);

Результат:
17
0,468
04.01.2021
21:56:06
08.01.2021 19:36:20
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032947
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Страдалецъ
Забил я на дженерики

давно пора от этой ереси избавиться
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032948
bk0010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator
Страдалецъ
Забил я на дженерики

давно пора от этой ереси избавиться
А в сях они нормально пашут...
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032949
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ,

То есть типа через TComparer<T>.Default было сложнее, да? )
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032974
Страдалецъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторТо есть типа через TComparer<T>.Default было сложнее, да? )
Я просто не понял как это делать, а когда попробовал сделать функцию Random через дженерики снова наступил на те-же грабли и просто бросил. Если не сложно, то покажите на моем конечном коде, как это будет через дженерики.
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032975
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
type
  TRange<T> = record
  private
    FMin, FMax: T;
    FComparer: IComparer<T>;
  public
    constructor Create(const MinValue, MaxValue: T);
    function Contains(const Value: T): Boolean;
  end;

{ TRange<T> }

function TRange<T>.Contains(const Value: T): Boolean;
begin
  Result := (FComparer.Compare(FMin, Value) <= 0) and
            (FComparer.Compare(Value, FMax) <= 0);
end;

constructor TRange<T>.Create(const MinValue, MaxValue: T);
begin
  FMin := MinValue;
  FMax := MaxValue;
  FComparer := TComparer<T>.Default;
end;
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032977
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function TRange<T>.Random: T;
begin
  case PTypeInfo(TypeInfo(T))^.Kind of
    TTypeKind.tkInteger,
    TTypeKind.tkInt64:
      begin
        var Min := TValue.From<T>(FMin).AsInt64();
        var Max := TValue.From<T>(FMax).AsInt64();
        Result := TValue.From<Int64>(Min + System.Random(Max - Min)).AsType<T>();
      end;
    //    .........  тут другие если надо
    else
      Result := Default(T);
  end;
end;
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032980
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ
Если не сложно, то покажите на моем конечном коде, как это будет через дженерики.

Если быстро, то так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
function TRange<T>.Contains(Value: T): Boolean;
begin

 case GetTypeKind(T) of

  tkInteger : case PTypeInfo(TypeInfo(T)).TypeData.OrdType of
               otSByte : Result := (ShortInt((@Value)^) >= ShortInt((@FMin)^)) And (ShortInt((@Value)^) <= ShortInt((@FMax)^));
               otUByte : Result := (Byte((@Value)^) >= Byte((@FMin)^)) And (Byte((@Value)^) <= Byte((@FMax)^));
               otSWord : Result := (SmallInt((@Value)^) >= SmallInt((@FMin)^)) And (SmallInt((@Value)^) <= SmallInt((@FMax)^));
               otUWord : Result := (Word((@Value)^) >= Word((@FMin)^)) And (Word((@Value)^) <= Word((@FMax)^));
               otSLong : Result := (Integer((@Value)^) >= Integer((@FMin)^)) And (Integer((@Value)^) <= Integer((@FMax)^));
               otULong : Result := (Cardinal((@Value)^) >= Cardinal((@FMin)^)) And (Cardinal((@Value)^) <= Cardinal((@FMax)^));
              else
               Error(reAssertionFailed);
              end;

  tkInt64   : Result := (Int64((@Value)^) >= Int64((@FMin)^)) And (Int64((@Value)^) <= Int64((@FMax)^));

  tkFloat   : if PTypeInfo(TypeInfo(T)).TypeData.FloatType = ftDouble then
               Result := (Double((@Value)^) >= Double((@FMin)^)) And (Double((@Value)^) <= Double((@FMax)^))
              else
               Error(reAssertionFailed);

 else
  Error(reAssertionFailed);
 end;

end;
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032983
Страдалецъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо. Уже понятнее. Есть от чего оттолкнуться.
Kazantsev Alexey - спасибо конечно, но это уже изврат, дженерики должны упрощать жизнь, а не глумится над кодером :)
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032984
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страдалецъ
дженерики должны упрощать жизнь, а не глумится над кодером :)

В FPC упрощают. А в дельфе - добро пожаловать
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032985
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Все бы хорошо, но в FPC генерики будут выдавать ошибки не на этапе компиляции как в дельфе, а во время работы ПО.

С этой точки зрения использование Comparer<T>.Default.Compare вместо прямого кода сравнения выглядит не столь ужасно.
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032986
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
но в FPC генерики будут выдавать ошибки не на этапе компиляции как в дельфе, а во время работы ПО

Ну что за глупости...
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032987
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Смотри:


Вариант для байта и строки откомпилировался, а на варианте с TVarData получили ошибку компиляции т.к. для TVarData не определён оператор сравнения. Если сейчас написать тайпхелпер с перегруженным оператором сравнения для TVarData, то и третий вариант откомпилируется. Круто, да?
...
Рейтинг: 0 / 0
Generics, а собственно как сравнить элементы <T> ?
    #40032989
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Если сейчас написать тайпхелпер с перегруженным оператором сравнения для TVarData, то и третий вариант откомпилируется.

Хотя нет, в хелпере оператор декларировать нельзя. Но, с любыми другими методами это работает.
...
Рейтинг: 0 / 0
25 сообщений из 49, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Generics, а собственно как сравнить элементы <T> ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]