導入
ラムダやふつうの関数を「変数に入れて持ち回りたい」「関数を引数として受け取りたい」――そんなときの汎用の入れ物が std::function です。コールバックや、あとで差し替えられる処理を表すのに使います。
説明
function<戻り値(引数の型)> という形で、関数・ラムダをまとめて入れられます。中身が何であれ、同じ型の変数として扱えます。
#include <iostream>
#include <functional> // std::function
using namespace std;
int addOne(int x) { return x + 1; } // ふつうの関数
int main() {
function<int(int)> f;
f = addOne; // 関数を入れる
cout << f(10) << endl; // 11
f = [](int x) { return x * 2; }; // ラムダも入れられる
cout << f(10) << endl; // 20
return 0;
}
関数を引数に取る関数を書けば、「処理を後から渡す」設計ができます。ボタンが押されたときの動作など、コールバックの表現に向きます。
flowchart LR caller["呼び出し側"] -->|"処理を渡す"| api["void apply(vector, function<...> op)"] api -->|"各要素に op を適用"| result["結果"]
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// 「各要素にどうするか」を関数として受け取る
void each(const vector<int>& v, function<void(int)> action) {
for (int x : v) action(x);
}
int main() {
vector<int> v = {1, 2, 3};
int sum = 0;
each(v, [&sum](int x) { sum += x; }); // 処理を渡す
cout << sum << endl; // 6
return 0;
}
まとめ
std::function<戻り値(引数)> は、関数・ラムダを入れられる汎用の入れ物です。「処理を変数に持つ」「処理を引数で受け取る」ことができ、コールバックや差し替え可能な設計に使います。テンプレート引数で受けるより柔軟ですが、少し実行コストがかかる点も覚えておきましょう。