std::move dan std::forward
Tukar lvalue kepada rvalue dengan std::move dan kekalkan kategori nilai dengan std::forward.
std::move dan std::forward ialah pelajaran C++ Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran C++ Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus C++ Academy merangkumi sejumlah 4 pelajaran.
Dua Saudara, Tugas Berbeza
std::move dan std::forward kedua-duanya ialah penukaran jenis semasa kompilasi. Rupa kedua-duanya serupa, tetapi masalah yang diselesaikan berbeza.
std::move: Sentiasa Menukar kepada rvalue
std::move(x) tanpa syarat menukar x kepada rujukan rvalue. Fungsi penerima kemudiannya boleh mengambil alih sumbernya.
std::string s = "Hello";
std::string t = std::move(s); // move-constructs t from s
// s is now in a valid-but-unspecified stateBila Perlu Menggunakan move
Gunakan std::move dalam:
- Pembina pemindahan dan operator penugasan pemindahan
- Pemulangan pemboleh ubah tempatan apabila anda mahu memaksa pemindahan (jarang diperlukan — RVO biasanya digunakan)
- Penghantaran pemboleh ubah tempatan yang tidak lagi diperlukan kepada fungsi yang mengambil alih pemilikan
Pelaksanaan std::move
Ia hanyalah static_cast yang disamarkan:
template <typename T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept {
return static_cast<typename std::remove_reference<T>::type&&>(t);
}std::forward: Mengekalkan Kategori
Dalam templat yang menggunakan rujukan penerusan (T&&), std::forward<T>(x) menukar x kembali kepada kategori asalnya (lvalue atau rvalue). Ia digunakan untuk penerusan sempurna.
template <typename T>
void wrapper(T&& arg) {
target(std::forward<T>(arg)); // forwards as lvalue or rvalue depending on T
}Mengapa Penerusan Diperlukan
Di dalam templat, parameter mempunyai nama — lalu menjadi lvalue, walaupun pemanggil menghantar rvalue. std::forward mendapatkan semula kategori asalnya.
Tanpa std::forward
Tanpa std::forward, setiap argumen akan dihantar sebagai lvalue di dalam wrapper, sekali gus menggagalkan sebarang semantik pemindahan yang dikehendaki pemanggil.
template <typename T>
void wrapper(T&& arg) {
target(arg); // always lvalue — wrong
}Sentiasa Nyatakan Parameter Templat kepada forward
std::forward<T> memerlukan argumen templat yang dinyatakan secara jelas. Tanpanya, tingkah laku akan menjadi tidak betul.
Contoh Penerusan Sempurna
Fungsi kilang yang meneruskan argumen pembina mengekalkan perbezaan rvalue dan lvalue demi kecekapan.
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}Pindahkan Sekali Sahaja
Setiap objek hendaklah dipindahkan paling banyak sekali. Selepas dipindahkan, objek berada dalam keadaan sah tetapi tidak ditentukan — biasanya anda menetapkan nilai baharu kepadanya atau memusnahkannya. Menggunakan objek yang telah dipindahkan tanpa menetapkan nilai baharu terlebih dahulu berisiko menyebabkan pepijat yang sukar dikesan.
Peraturan Umum
Model mental ringkas:
- Mempunyai jenis konkrit dan mahu memindahkannya →
std::move - Mempunyai parameter templat dan mahu mengekalkan kategori →
std::forward<T>
Semakan Pantas
Di dalam fungsi templat dengan parameter T&& arg, bagaimanakah anda meneruskan arg sambil mengekalkan kategorinya sebagai lvalue atau rvalue?
Ringkasan
std::move tanpa syarat menukar kepada rvalue — gunakannya pada objek konkrit yang sumbernya ingin anda ambil alih. std::forward<T> mengekalkan kategori nilai di dalam templat generik — gunakannya untuk penerusan sempurna.
Pelajari C++ dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 51
- Pelajaran
- 203
Soalan Lazim
Adakah pelajaran “std::move dan std::forward” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran C++ Academy, termasuk “std::move dan std::forward”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus C++ Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “std::move dan std::forward”?
Tukar lvalue kepada rvalue dengan std::move dan kekalkan kategori nilai dengan std::forward. Anda berlatih C++ Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan C++ Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran C++ Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “std::move dan std::forward” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran C++ Academy ini?
Ya. Setiap pelajaran C++ Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Lvalue berbanding Rvalue: Perbezaannya
- Rujukan Rvalue dan Sintaks &&
- std::move dan std::forward
- Pembina Move dan Tugasan Move