5

次のようなデフォルトのパラメーターを使用して関数ポインターを作成することは可能ですか

TFunctionPointer = function(sName:AnsiString; tOptional: TObject = nil):smallint;

私が達成したいこと:

タイプの関数を受け入れることができる関数ポインタ

function A(sName:AnsiString)

また

function B(sName:AnsiString, tOptional: TObject)

どうすればこれを達成できますか?

4

2 に答える 2

7

デフォルトのパラメーターは単なる構文糖衣です。実際には、関数呼び出しには 2 つのパラメーターがあります。

ただし、関数参照と匿名メソッドを使用して、そのような関数ポインター (関数アダプター) を作成できます。

type
  fnA = function(const sName: AnsiString): integer;
  fnB = function(const sName: AnsiString; const tOptional: TObject); integer;

  fnRef = reference to function(const sName: AnsiString; const tOptional: TObject): integer;

  fnBridge = record 
     Bridge: fnRef;
     class operator Implicit(fn: fnA): fnBridge;
     class operator Implicit(fn: fnB): fnBridge;
  end;

class operator fnBridge.Implicit(fn: fnA): fnBridge;
begin
  Result.Bridge := 
     function(const sName: AnsiString; const tOptional: TObject): integer
     begin
       Result := fn(sName); 
     end;
end;

class operator fnBridge.Implicit(fn: fnB): fnBridge;
begin
  Result.Bridge := 
     function(const sName: AnsiString; const tOptional: TObject): integer
     begin
       Result := fn(sName, tOptional); 
     end;
end;

function A(const sName: AnsiString): integer; 
begin Result := Length(sName) end;

function B(const sName: AnsiString; const tOptional: TObject): integer; 
begin Result := Length(sName) - Length(tOptional.ClassName) end;

function Consumer (const Param1, Param2: integer; const Action: fnBridge): integer;
begin
  Result := Param1 + Param2 * Action.Bridge('ABCDE', Application);
end;

....
  ShowMessage( IntToStr( Consumer(10, 20, A) ));
  ShowMessage( IntToStr( Consumer(10, 20, B) ));

PS: Delphi のバージョンが指定されていないため、Delphi のどのバージョンでも問題なく回答できることを意味します。このメソッドは、Delphi 2009 以降のハニー バージョンで機能するはずです。

PPS: キャプチャされた変数を持つ関数への参照は、TInterfacedObject子孫として内部的に実装されます。全体として、これは「高階関数」を使用した「戦略パターン」の縮小ケースにすぎません

于 2013-11-06T09:20:55.623 に答える