6

私は D2010 を使用していますが、64 ビット版がリリースされるまで使用し続ける必要があります。

ジェネリックでは、ジェネリック型へのポインターはサポートされていませんが、非常に便利だと思います。SO (2009 年の投稿) の他の場所で読みましたが、Barry Kelly 卿は、これは将来変更される可能性があると考えていました。これが XE でサポートされているかどうかは誰にもわかりませんか?

そうでない場合は、XE2 に組み込まれることを切に願っています。

ありがとう。

4

3 に答える 3

5

XE (2011) の場合:

これは機能します:

type
  TTest1<T> = record
    FX : T;
  end;

  TTest2<T> = array of T;

これはうまくいきません:

type
  TTest3<T> = ^TTest1<T>;
  TTest4<T> = ^TTest2<T>;
  TTest<T> = ^T;

そのため、ジェネリックへのポインターはまだ使用できません。

ただし、次のことができます。

type
  TMyClass = class
  public
    class function GetAddr<T>(const AItem: T): Pointer;
    class function GetP<T>(const APtr: Pointer): T;
  end;

class function TMyClass.GetAddr<T>(const AItem: T): Pointer;
begin
  Result := @AItem;
end;

class function TMyClass.GetP<T>(const APtr: Pointer): T;
begin
  Result := T(APtr^);
end;

ジェネリック関数を持つことはできませんが、ジェネリック メソッドを持つことはできます。

したがって、これを使用すると、ジェネリックへのポインターを使用できますが、この汚い手法を使用すると型の安全性がないことに注意してください。

于 2011-01-08T20:45:08.977 に答える
2

ジェネリック型へのAfaikポインターは、ジェネリック内にネストされた場合にのみサポートされます。

Type
   tbwimagegen <T > = Class(TBaseImage)
             Type
                TLocalType =tbwimagegen <T>;
                BaseUnit = T;
                RefT= ^BaseUnit;
              end;

これを使用して、画像処理コード(T = 8,16,32ビット整数またはRGBAレコード)をタイプごとに簡単に切り替えることができます。特殊化を切り替えるだけで、ネストされた型を使用するコードが適応します。

もちろん、すべてのジェネリックと同様に、特殊なタイプのみを使用できます。これは、汎用の非特殊タイプのコードに対してコードが生成されないためです。(専門化時間までのみ保存されます)

更新:残念ながら、http: //qc.embarcadero.com/wc/qcmain.aspx ?d=99703に遭遇しました。

于 2011-01-08T21:54:34.750 に答える
2

注: 次の回答は間違っています。前提に欠陥があるためです。赤面を保存するために全体を編集するのではなく、エラーを強調するコメントが意味をなすようにそのまま残しました。

どうすればこれを安全にサポートできるでしょうか?

与えられた(これがあなたが念頭に置いているものである場合、私はそれだと思います):

  type
    TFoo<T> = class end;
    PFoo<T> = ^TFoo<T>;

次に、次の場合:

  var
    a, b: TFoo<T>;
    p: PFoo<T>;

  a := TFoo<String>.Create;
  b := TFoo<Integer>.Create;

その場合、次の両方が許容されます。

  p := @a;

  p := @b;

任意の時点でpは T の任意の TFoo を逆参照する可能性がありますが、常に特定のTのみを参照できます。コードがpを正しく逆参照することを保証する、タイプセーフなコンパイル時のメカニズムが見当たりません。

この問題を回避する 1 つの方法 (コンパイラの制限ではなく、タイプ セーフを単に表現できないタイプ セーフな方法で何かを表現しようとすることの制限) は、これらの型の型固有の派生物を作成して使用することです。それらの。逆参照したい時点で、とにかく型Tを知っていることはほぼ確実です。

  type
    TFoo<T> = class end;

    TFooString = TFoo<String>;
    PFooString = ^TFooString;


  var
     p: PFooString;


  a := TFoo<Integer>;
  b := TFoo<String>;


  p := @a;  // Should not compile
  p := @b;  // This is OK

これは、Delphi 2010 でも可能です。

しかし、心配なことに、これを調査すると、次のことがわかります。

  p := @a;  // Should not compile

実際にコンパイルします。これは間違っていると思います。大きな過ち。また、Delphi でのジェネリック実装の(まだ)別の欠陥を指摘している可能性もあります。

ここにドラゴンがいる...

于 2011-01-08T20:44:07.670 に答える