Saya melihat ini di sini: Pindahkan Konstruktor memanggil basis-kelas Pindahkan Konstruktor
Bisakah seseorang menjelaskan:
- perbedaan antara
std::move
danstd::forward
, lebih disukai dengan beberapa contoh kode? - Bagaimana memikirkannya dengan mudah, dan kapan menggunakannya
c++
c++11
perfect-forwarding
aCuria
sumber
sumber
move
saat Anda ingin memindahkan suatu nilai, danforward
kapan Anda ingin menggunakan penerusan yang sempurna. Ini bukan ilmu roket di sini;)Jawaban:
std::move
mengambil objek dan memungkinkan Anda untuk memperlakukannya sebagai sementara (suatu nilai). Meskipun ini bukan persyaratan semantik, biasanya fungsi yang menerima referensi ke nilai akan membatalkannya. Ketika Anda melihatstd::move
, itu menunjukkan bahwa nilai objek tidak boleh digunakan setelahnya, tetapi Anda masih dapat menetapkan nilai baru dan terus menggunakannya.std::forward
memiliki satu kasus penggunaan: untuk melemparkan parameter fungsi templated (di dalam fungsi) ke kategori nilai (nilai atau nilai) pemanggil yang digunakan untuk meneruskannya. Ini memungkinkan argumen nilai diturunkan sebagai nilai, dan nilai dinilai sebagai nilai, sebuah skema yang disebut "penerusan yang sempurna."Untuk menggambarkan :
Seperti yang disebutkan Howard, ada juga kesamaan karena kedua fungsi ini hanya menggunakan tipe referensi. Tetapi di luar kasus penggunaan khusus ini (yang mencakup 99,9% dari kegunaan cast referensi nilai), Anda harus menggunakan
static_cast
secara langsung dan menulis penjelasan yang baik tentang apa yang Anda lakukan.sumber
std::forward
's hanya kasus yang digunakan adalah forwarding sempurna dari argumen fungsi. Saya telah mengalami situasi di mana saya ingin meneruskan hal-hal lain dengan sempurna, seperti anggota objek.Keduanya
std::forward
danstd::move
tidak lain adalah gips.Di atas melemparkan ekspresi lvalue
x
tipe X ke ekspresi rvalue tipe X (nilai x lebih tepatnya).move
juga dapat menerima nilai:dan dalam hal ini ini adalah fungsi identitas: mengambil nilai tipe X dan mengembalikan nilai tipe X.
Dengan
std::forward
Anda dapat memilih tujuan sampai batas tertentu:Melemparkan ekspresi nilai
x
dari tipe X ke ekspresi tipe Y. Ada kendala pada apa yang bisa Y.Y dapat menjadi Pangkalan X yang dapat diakses, atau referensi ke Pangkalan X. Y dapat menjadi X, atau referensi ke X. Seseorang tidak dapat membuang kualifikasi cv
forward
, tetapi seseorang dapat menambahkan kualifikasi cv. Y tidak dapat menjadi tipe yang hanya dapat dikonversi dari X, kecuali melalui konversi Basis yang dapat diakses.Jika Y adalah referensi lvalue, hasilnya akan menjadi ekspresi lvalue. Jika Y bukan referensi lvalue, hasilnya akan menjadi ekspresi rvalue (xvalue tepatnya).
forward
dapat mengambil argumen nilai hanya jika Y bukan referensi nilai tinggi. Artinya, Anda tidak dapat memberikan nilai ke nilai. Ini untuk alasan keamanan karena melakukan hal itu biasanya mengarah pada referensi yang menggantung. Tapi casting nilai untuk nilai adalah baik dan diizinkan.Jika Anda mencoba menentukan Y untuk sesuatu yang tidak diizinkan, kesalahan akan ditangkap pada waktu kompilasi, bukan waktu berjalan.
sumber
std::forward
, maka setelah fungsi itu dijalankan, dapatkah saya menggunakan objek itu? Saya menyadari bahwa, dalam kasusstd::move
, itu adalah perilaku yang tidak terdefinisi.move
: stackoverflow.com/a/7028318/576911 Untukforward
, jika Anda memberikan nilai lvn, API Anda akan bereaksi seolah menerima nilai lvn. Biasanya ini berarti nilainya akan tidak dimodifikasi. Tetapi jika ini bukan nilai konstanta, API Anda mungkin telah memodifikasinya. Jika Anda memberikan nilai, ini biasanya berarti bahwa API Anda mungkin telah pindah dari itu, dan dengan demikian stackoverflow.com/a/7028318/576911 akan berlaku.std::forward
digunakan untuk meneruskan parameter persis seperti itu diteruskan ke suatu fungsi. Seperti yang ditunjukkan di sini:Kapan harus menggunakan argumen std :: forward to forward?
Menggunakan
std::move
menawarkan objek sebagai nilai, untuk mungkin cocok dengan konstruktor bergerak atau fungsi yang menerima nilai. Itu melakukan itustd::move(x)
bahkan jikax
bukan nilai sendiri.sumber