Menerokai Pelaksanaan std::function
Dalam dunia ungkapan lambda, tanggapan saiz menjadi cair, kerana ia pada asasnya dibungkus dalam kelas dengan rujukan bersaiz berubah-ubah. Walau bagaimanapun, std::function memerlukan saiz tetap. Ini menimbulkan persoalan: bagaimanakah perkara ini didamaikan?
Jawapannya terletak pada pemadaman jenis. Mari kita bayangkan pelaksanaan yang dipermudahkan:
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); } };
Dalam pendekatan ringkas ini, std::function menyimpan penunjuk unik ke kelas asas. Untuk setiap functor yang berbeza, jenis terbitan dicipta dan dibuat instantiated secara dinamik. Oleh itu, saiz std::fungsi kekal malar sambil menampung julat fungsi pada timbunan.
Teknik pengoptimuman memperhalusi lagi skema ini, menggunakan pengoptimuman objek kecil, mengelakkan penyimpangan dan sebagainya. Walau bagaimanapun, dari segi konsep, idea teras tetap sama.
Mengenai salinan std::function, bukti eksperimen mencadangkan salinan bebas objek boleh panggil. Contoh rekaan:
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) }
Output menunjukkan salinan terpencil dan bukannya keadaan dikongsi, kerana seruan berbeza menambah nilai secara bebas.
Atas ialah kandungan terperinci Bagaimanakah std::function Mengekalkan Saiz Tetap Walaupun Mengendalikan Ungkapan Lambda Bersaiz Boleh Ubah?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!