二度目の質問をお許しください。
先ほどの関数渡しは成功したのですが、少し入れ子にしてプログラムを組んでみたところ、例外が発生してしまいました。
function Foo(Func: TFunction; x:Real): Real;
begin
Result:= Func(x);
end;
function Bar(Func: TFunction; a: Real; t: Real): Real;
function Quux(x: Real): Real;
begin
Result:= Func(x)*a;
end;
begin
Result:= Foo(@Quux, t);
end;
procedure Button2Click(Sender: TObject);
function Half(x: Real): Real;
begin
Result:= x/2;
end;
begin
ShowMessage( FloatToStr( Bar( @Half, 3, 1 ) ) );
end;
Button2 を押すと、関数 Half に 3 をかけたものに、引数 x = 1 を代入した値を返す意図のプログラムを書きました。
しかし、「アドレス xxxxxxxx でアドレス xxxxxxxx に対する読み込み違反が発生しました。」と表示されてしまいます。
何か解決法はないものでしょうか?
関数内関数は外側の関数の引数が有効なのは、その関数から呼ばれたときだけです。
ですから、
function Quux(x: Real): Real;
begin
Result:= Func(x)*a;
end;
で、Foo から Quux が実行されるとき、Func と a は不定です。試しに
function Quux(x: Real): Real;
begin
Result:= 1.23;
end;
としてみると分かります。これは当然で、外側の関数と無関係に呼ばれてしまう場合に
正常に動くはずはないからです。
ありがとうございます。確かにそう考えてみるとそうですね。
と、なると、同様の意図のプログラムは作ることはできないでしょうか?
何か別の形で実現することは可能ですか?
ツイート | ![]() |