std::function: 実装とメモリ管理
std::function クラスは、呼び出し可能なオブジェクトの汎用ラッパーとして機能し、呼び出し可能な型の保存と呼び出し。ラムダ式は関数呼び出し演算子を備えたクラスとして実装されることがよくありますが、そのサイズは参照される変数の数に応じて大幅に変化する可能性があります。
対照的に、std::function はさまざまな種類の呼び出し可能関数に対応しながら固定サイズを維持する必要があります。 、ラムダを含む。その実装は型消去に依存しており、これには呼び出し可能なエンティティを表す基本クラスの作成が含まれます。 std::function で使用される特定の呼び出し可能型ごとに、派生クラスが作成され、動的にインスタンス化されます。
たとえば、double-to-int 関数の 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) {} int operator()(double d) { return functor(d); } };
std::function オブジェクトには、基本クラスに対する unique_ptr が含まれます。 std::function が特定の呼び出し可能オブジェクトを使用して構築されると、派生クラスが作成され、ヒープ上にインスタンス化されます。 std::function オブジェクト自体は固定サイズのままですが、呼び出し可能なオブジェクトのメモリは動的に割り当てられます。
コピー セマンティクスに関しては、各 std::function オブジェクトは呼び出し可能なエンティティの独自のコピーを維持します。これは、次のテストから明らかです。
fun f1 = [=]() mutable { std::cout << value++ << '\n' }; fun f2 = f1; f1(); f2(); f3();
プログラムの出力は、f2 と f3 がそれぞれ別個の呼び出し可能オブジェクトを維持し、その結果、異なる増分値が出力されることを示しています。したがって、 std::function は、 std::function オブジェクトのコピーが独自の独立した呼び出し可能エンティティを維持するようにしながら、その呼び出し可能オブジェクトのメモリを管理します。
以上が`std::function` はメモリと呼び出し可能なオブジェクトをどのように管理しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。