1. "Apa itu?"
Sementara std::move()
secara teknis fungsi - saya akan mengatakan tidak benar-benar fungsi . Ini semacam konverter antara cara kompiler mempertimbangkan nilai ekspresi.
2. "Apa fungsinya?"
Hal pertama yang perlu diperhatikan adalah std::move()
tidak benar-benar memindahkan apa pun . Itu mengkonversi ekspresi dari menjadi nilai (seperti variabel bernama) menjadi nilai x . Nilai x memberi tahu kompilator:
Anda dapat menjarah saya, memindahkan apa pun yang saya pegang dan menggunakannya di tempat lain (karena bagaimanapun saya akan segera dihancurkan) ".
dengan kata lain, saat Anda menggunakan std::move(x)
, Anda mengizinkan penyusun mengkalibkan x
. Jadi jika x
memiliki, katakanlah, buffernya sendiri dalam memori - setelah std::move()
kompiler dapat memiliki objek lain memilikinya.
Anda juga dapat beralih dari nilai awal (seperti sementara yang Anda lewati), tetapi ini jarang berguna.
3. "Kapan itu harus digunakan?"
Cara lain untuk mengajukan pertanyaan ini adalah "Untuk apa saya bisa mematikan sumber daya objek yang ada?" baik, jika Anda menulis kode aplikasi, Anda mungkin tidak akan main-main dengan benda-benda sementara yang dibuat oleh kompiler. Jadi terutama Anda akan melakukan ini di tempat-tempat seperti konstruktor, metode operator, fungsi standar-perpustakaan-seperti algoritma dll. Di mana objek bisa dibuat dan dihancurkan secara otomatis banyak. Tentu saja, itu hanya aturan praktis.
Penggunaan tipikal adalah memindahkan sumber daya dari satu objek ke objek lain alih-alih menyalin. @Guillaume menghubungkan ke halaman ini yang memiliki contoh singkat langsung: menukar dua objek dengan sedikit penyalinan.
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
menggunakan gerakan memungkinkan Anda untuk menukar sumber daya alih-alih menyalinnya:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Pikirkan apa yang terjadi ketika T
, katakanlah, vector<int>
ukuran n. Pada versi pertama Anda membaca dan menulis elemen 3 * n, pada versi kedua Anda pada dasarnya membaca dan menulis hanya 3 pointer ke buffer vektor, ditambah ukuran 3 buffer. Tentu saja, kelas T
perlu tahu bagaimana melakukan gerakan; kelas Anda harus memiliki operator penugasan bergerak dan konstruktor gerakan agar kelas T
dapat berfungsi.