Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Generics, а собственно как сравнить элементы <T> ? / 25 сообщений из 49, страница 1 из 2
31.12.2020, 23:40
    #40032918
Страдалецъ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics, а собственно как сравнить элементы <T> ?
Делаю простенькую штуку и получаю ошибку компиляции:
Код: 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
01.01.2021, 01:16
    #40032924
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics, а собственно как сравнить элементы <T> ?
Страдалецъ
И как это правильно сделать?

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

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

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

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

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

пробуй так:

Код: 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
01.01.2021, 02:16
    #40032932
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics, а собственно как сравнить элементы <T> ?
SOFT FOR YOU
До твоего комментария я думал, что в FPC как раз всё печально )

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

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

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

Код: 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
01.01.2021, 13:34
    #40032947
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics, а собственно как сравнить элементы <T> ?
Страдалецъ
Забил я на дженерики

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

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

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

Код: 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
01.01.2021, 17:42
    #40032977
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics, а собственно как сравнить элементы <T> ?
Страдалецъ,

Код: 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
01.01.2021, 18:24
    #40032980
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Generics, а собственно как сравнить элементы <T> ?
Страдалецъ
Если не сложно, то покажите на моем конечном коде, как это будет через дженерики.

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

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

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

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

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

Смотри:


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

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


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