[解決済み] 関数ポインタ、クロージャ、ラムダ
質問
私は今ちょうど関数ポインタについて学んでいるところですが、このテーマに関する K&R の章を読んでいたとき、最初に私を襲ったのは、「あれ、これってクロージャに似てる」でした。
では、なぜ C スタイルの関数ポインタはクロージャやラムダと根本的に違うのでしょうか。私が言える限り、それは、関数を匿名で定義する慣習とは対照的に、関数ポインタがまだ定義された (名前の付いた) 関数を指しているという事実と関係があります。
なぜ、関数に関数を渡すことは、渡されるのが普通の日常的な関数である最初のケースよりも、無名の2番目のケースの方が強力であると見なされるのでしょうか?
この2つを密接に比較することがどのように、そしてなぜ間違っているのか、教えてください。
ありがとうございます。
どのように解決するのですか?
ラムダ(または クロージャ ) は、関数ポインタと変数の両方をカプセル化します。これが、C#で、できる理由です。
int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
return i < lessThan;
};
私はそこで匿名のデリゲートをクロージャとして使い(その構文はラムダと同等のものよりも少し明確でCに近い)、lessThan(スタック変数)をクロージャに取り込んでいます。クロージャが評価されるとき、lessThan (そのスタック・フレームは破壊されたかもしれない) は参照され続けるだろう。もし私が lessThan を変更したら、比較を変更する。
int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
return i < lessThan;
};
lessThanTest(99); // returns true
lessThan = 10;
lessThanTest(99); // returns false
C言語では、これは違法となります。
BOOL (*lessThanTest)(int);
int lessThan = 100;
lessThanTest = &LessThan;
BOOL LessThan(int i) {
return i < lessThan; // compile error - lessThan is not in scope
}
引数を2つ取る関数ポインタを定義することができますが。
int lessThan = 100;
BOOL (*lessThanTest)(int, int);
lessThanTest = &LessThan;
lessThanTest(99, lessThan); // returns true
lessThan = 10;
lessThanTest(100, lessThan); // returns false
BOOL LessThan(int i, int lessThan) {
return i < lessThan;
}
しかし、今私はそれを評価するときに2つの引数を渡さなければならない。lessThan がスコープにない別の関数にこの関数ポインタを渡したい場合は、チェーンの各関数に渡すか、グローバルに昇格させるかして、手動でそれを維持する必要があります。
クロージャをサポートするほとんどの主流の言語は無名関数を使用しますが、そのための要件はありません。無名関数なしでクロージャを持つことができ、クロージャなしで無名関数を持つことができます。
まとめ:クロージャとは、関数ポインタ+捕捉変数の組み合わせである。
関連
-
_CRT_SECURE_NO_WARNINGS エラーメッセージ、解決方法
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] リスト内包とラムダ+フィルタの比較
-
[解決済み] クロージャ」と「ラムダ」の違いは何ですか?
-
[解決済み] Distinct() with lambda?
-
[解決済み] ラムダ(関数)とは何ですか?
-
[解決済み] C言語で関数をパラメータとして渡すにはどうすればよいですか?
-
[解決済み】C++11のラムダ式って何?
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
-
[解決済み】ラムダ関数のクロージャは何を捕捉するのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
C++の配列コピー
-
関数 'malloc' の暗黙の宣言に対する解決策
-
[解決済み] Code::Blocks アプリケーションをコンパイルできない
-
[解決済み] C関数から文字列を返す
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] クロージャ」と「ラムダ」の違いは何ですか?
-
[解決済み] なぜ16進数には0xがつくのですか?