Cara std::function Dilaksanakan: Type-Erasure dan Timbunan Peruntukan
Perincian pelaksanaan utama std::function ialah keupayaannya untuk membalut sebarang boleh dipanggil, termasuk ungkapan lambda. Walaupun saiz lambda berbeza-beza, fungsi std:: mengekalkan saiz tetap. Ini dicapai melalui teknik yang dipanggil type-erasure.
Ambil contoh ringkas 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); } };
Di sini, std::function holds satu_ptr unik kepada jenis asas callable_base. Untuk setiap fungsi unik yang digunakan, jenis terbitan boleh dipanggil
Salinan std::function mencetuskan salinan objek boleh panggil dalaman, dan bukannya berkongsi keadaan. Ini terbukti daripada ujian di mana nilai pembolehubah yang ditangkap boleh ubah dinaikkan:
int value = 5; std::function<void()> f1 = [=]() mutable { std::cout << value++ << '\n'; }; std::function<void()> f2 = f1; // Prints 5 f1(); // Prints 5 (copy of mutable state) f2();
Oleh itu, fungsi std:: membungkus pemboleh panggil dengan pelbagai saiz dengan cekap menggunakan pemadaman jenis dan peruntukan timbunan. Peruntukan timbunan digunakan untuk membuat instantiate jenis dinamik berdasarkan pembalut boleh panggil, memastikan saiz tetap untuk std::function itu sendiri.
Atas ialah kandungan terperinci Bagaimanakah `std::function` Mencapai Saiz Tetap Walaupun Membungkus Pemakaian Boleh Panggil Berbeza Saiz?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!