1. ホーム
  2. c++

C++のラムダ式の寿命は?

2023-10-30 16:19:27

質問

(私が読んだのは C++でラムダ由来の暗黙のファンクタの寿命はどのくらいでしょうか? を既に読みましたが、この質問には答えていません)。

C++のラムダ構文は、呼び出し演算子といくつかの状態を持つ匿名クラスのインスタンスを作成するための単なる砂糖であることを理解し、その状態の寿命要件(参照によって値によってキャプチャするかどうかによって決まる)を理解しています。次の例では std::function のインスタンスが返されますが、これは役に立つのでしょうか?

std::function<int(int)> meta_add(int x) {
    auto add = [x](int y) { return x + y; };
    return add;
}

もし、それが どのように動作するのか ? これはちょっと魔法が多すぎるような気がします。 std::function がインスタンス全体をコピーすることで動作するとしか考えられず、キャプチャしたものによっては非常に重くなります。 std::function は主に素の関数ポインタで使っていて、それらのコピーはすぐに終わります。また、以下の点からも問題があると思われます。 std::function の型消去に照らしても問題があるように思えます。

どのように解決するのですか?

ラムダをハンドロールファンクタに置き換えた場合の寿命は、まさにその通りです。

struct lambda {
   lambda(int x) : x(x) { }
   int operator ()(int y) { return x + y; }

private:
   int x;
};

std::function<int(int)> meta_add(int x) {
   lambda add(x);
   return add;
}

オブジェクトが作成され、ローカルで meta_add 関数の値も含め、その内部で移動します。 x を含む全体] を返り値に移動した場合、ローカルインスタンスはスコープ外に出て、通常通り破壊されます。 しかし、関数から返されるオブジェクトは std::function オブジェクトが保持する限り有効です。 それがどれくらいの期間かは、明らかに呼び出し側のコンテキストに依存します。