Pengenalan
Dalam C , menangkap melalui gerakan, juga dikenali sebagai rujukan rnilai, membenarkan untuk pemindahan pemilikan yang cekap sesuatu objek kepada ungkapan lambda. Teknik ini boleh berguna terutamanya dalam situasi di mana sumber objek perlu diuruskan secara eksplisit dalam lambda.
Dalam C 14, tangkapan lambda umum menyediakan penyelesaian yang elegan untuk tangkapan bergerak. Dengan ciri ini, adalah mungkin untuk mengisytiharkan ungkapan lambda yang menangkap pembolehubah mengikut nilai menggunakan semantik bergerak:
using namespace std; auto u = make_unique<some_type>(some, parameters); go.run([u = move(u)] { do_something_with(u); });
Pendekatan ini memindahkan pemilikan u ke dalam lambda, memastikan sumber dikeluarkan dengan sewajarnya. Selain itu, jika objek perlu dialihkan keluar dari lambda, lambda mesti diisytiharkan sebagai boleh ubah.
Dalam C 11, move capture tidak secara langsung disokong. Walau bagaimanapun, terdapat teknik yang boleh mencontohi tingkah laku ini. Satu pendekatan ialah menggunakan fungsi pembantu untuk mencipta rujukan nilai (rref):
template <typename T> struct rref_impl { rref_impl() = delete; rref_impl(T &&x) : x(std::move(x)) {} // ... (remaining implementation) }; template<typename T> rref_impl<T> make_rref(T &&x) { return rref_impl<T>{std::move(x)}; }
Menggunakan fungsi pembantu ini, adalah mungkin untuk menangkap objek dengan bergerak dalam lambda:
unique_ptr<int> p{new int(0)}; auto rref = make_rref(std::move(p)); auto lambda = [rref]() mutable -> unique_ptr<int> { return rref.move(); };
Perhatikan bahawa lambda diisytiharkan sebagai boleh ubah untuk membenarkan pengubahsuaian rujukan nilai yang ditangkap.
Satu lagi pendekatan untuk meniru tangkapan lambda umum dalam C 11 ialah menggunakan kelas tersuai untuk menangkap pembolehubah dan menyediakan cara untuk mengalihkannya keluar daripada lambda:
template <typename T, typename F> struct capture_impl { T x; F f; // ... (remaining implementation) }; template <typename T, typename F> capture_impl<T,F> capture(T &&x, F &&f) { return capture_impl<T,F>(std::forward<T>(x), std::forward<F>(f)); }
Kelas ini boleh digunakan untuk menangkap pembolehubah dengan bergerak dan menyediakan cara untuk menggunakan lambda:
unique_ptr<int> p{new int(0)}; auto lambda = capture(std::move(p), [](unique_ptr<int> &p) { return std::move(p); });
Berbeza dengan pendekatan sebelumnya, lambda ini tidak boleh disalin, jika jenis yang ditangkap tidak boleh disalin. Ini menghalang kemungkinan ralat semasa menyalin lambda.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Menangkap Objek dengan Cekap dengan Bergerak dalam Ungkapan C Lambda?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!