ホームページ >バックエンド開発 >C++ >可変サイズのラムダ式を処理しているにもかかわらず、std::function はどのようにして固定サイズを維持するのでしょうか?

可変サイズのラムダ式を処理しているにもかかわらず、std::function はどのようにして固定サイズを維持するのでしょうか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-04 17:01:15619ブラウズ

How Does std::function Maintain a Fixed Size Despite Handling Variable-Sized Lambda Expressions?

std::function の実装の探索

ラムダ式の世界では、サイズの概念が流動的になります。基本的には、可変サイズの参照を持つクラスでラップされます。ただし、 std::function は固定サイズを必要とします。これは疑問を引き起こします: これはどのように調和するのでしょうか?

答えはタイプ消去にあります。単純化された実装を想像してみましょう。

struct callable_base {
   virtual int operator()(double d) = 0;
   virtual ~callable_base() {}
};
template <typename F>
struct callable : callable_base {
   F functor;
   callable(F functor) : functor(functor) {}
   virtual int operator()(double d) { return functor(d); }
};
class function_int_double {
   std::unique_ptr<callable_base> c;
public:
   template <typename F>
   function(F f) {
      c.reset(new callable<F>(f));
   }
   int operator()(double d) { return c(d); }
};

この単純化されたアプローチでは、std::function は基本クラスへの一意のポインターを格納します。個別のファンクターごとに派生型が作成され、動的にインスタンス化されます。したがって、 std::function のサイズは一定のままですが、ヒープ上のファンクターの範囲に対応します。

最適化手法では、小さなオブジェクトの最適化を使用したり、間接化を回避したりして、このスキームをさらに洗練させています。ただし、概念的には、中心的な考え方は同じままです。

std::function のコピーに関しては、実験的証拠により、呼び出し可能オブジェクトの独立したコピーが示唆されています。不自然な例:

int main() {
   int value = 5;
   typedef std::function<void()> fun;
   fun f1 = [=]() mutable { std::cout << value++ << '\n' };
   fun f2 = f1;
   f1(); // prints 5
   fun f3 = f1;
   f2(); // prints 5
   f3(); // prints 6 (copy after first increment)
}

異なる呼び出しによって値が個別に増加するため、出力は共有状態ではなく分離されたコピーを示します。

以上が可変サイズのラムダ式を処理しているにもかかわらず、std::function はどのようにして固定サイズを維持するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。