Rumah > pembangunan bahagian belakang > C++ > Bagaimanakah std::move() mengikat kepada lvalues ​​apabila rujukan rvalue sepatutnya hanya mengikat kepada rvalues?

Bagaimanakah std::move() mengikat kepada lvalues ​​apabila rujukan rvalue sepatutnya hanya mengikat kepada rvalues?

DDD
Lepaskan: 2024-11-14 10:46:01
asal
1070 orang telah melayarinya

How does std::move() bind to lvalues when rvalue references are supposed to only bind to rvalues?

Merungkai Misteri Sihir Penukaran std::move

Apabila menggunakan std::move(), adalah membingungkan untuk melihat bahawa yang dirujuk parameter rvalue boleh terikat kepada lvalues, yang biasanya dihadkan daripada melekat pada rujukan rvalue. Menyelidiki pelaksanaan std::move() mendedahkan kunci kepada paradoks yang jelas ini.

Membedah Pelaksanaan std::move()

Bermula dengan yang diperhalusi versi std::move():

template <typename T>
typename remove_reference<T>::type&& move(T&& arg) {
  return static_cast<typename remove_reference<T>::type&&>(arg);
}
Salin selepas log masuk

Kes 1: Menyebut move() dengan Rvalues

Apabila move() digunakan dengan rvalues, seperti objek sementara:

Object a = std::move(Object()); // Object() is temporary, hence prvalue
Salin selepas log masuk

Instasiasi templat yang terhasil ialah:

remove_reference<Object>::type&& move(Object&& arg) {
  return static_cast<remove_reference<Object>::type&&>(arg);
}
Salin selepas log masuk

Memandangkan remove_reference mengubah T& menjadi T atau T&& kepada T dan Objek ialah nilai biasa, morfologi fungsi terakhir menjadi:

Object&& move(Object&& arg) {
  return static_cast<Object&&>(arg);
}
Salin selepas log masuk

Pelakon adalah penting kerana rujukan nilai yang dinamakan dianggap sebagai nilai l.

Kes 2: Mendapatkan langkah() dengan Lnilai

Apabila move() digunakan dengan lvalues:

Object a; // a is an lvalue
Object b = std::move(a);
Salin selepas log masuk

Instasiasi move() yang terhasil ialah:

remove_reference<Object&>::type&& move(Object& && arg) {
  return static_cast<remove_reference<Object&>::type&&>(arg);
}
Salin selepas log masuk

Sekali lagi, remove_reference menterjemah Object& kepada Object, menghasilkan:

Object&& move(Object& && arg) { return static_cast(arg); }

Oleh itu, Object& && sebenarnya diterjemahkan kepada Object&, rujukan nilai lazim yang mengikat nilai dengan mudah.

The Fungsi Terhasil

Object & && = Object &
Object & &&& = Object &
Object && & = Object &
Object && &&& = Object &&
Salin selepas log masuk

Dengan peraturan ini dimainkan, fungsi terakhir menjadi:

Mencerminkan instantiasi untuk nilai r, ia memberikan hujahnya kepada rujukan nilai, dengan itu memastikan tingkah laku seragam .

Kepentingan remove_reference

Object&& move(Object& arg) {
  return static_cast<Object&&>(arg);
}
Salin selepas log masuk

Tujuan remove_reference menjadi jelas apabila memeriksa fungsi alternatif:

Apabila digunakan dengan nilai l:

menggunakan peraturan rujukan yang runtuh mendedahkan fungsi seperti pergerakan yang tidak boleh digunakan, mengembalikan nilai untuk argumen nilai. Penyebabnya ialah ketiadaan remove_reference, yang menghalang penukaran yang betul kepada rujukan rnilai.

Atas ialah kandungan terperinci Bagaimanakah std::move() mengikat kepada lvalues ​​apabila rujukan rvalue sepatutnya hanya mengikat kepada rvalues?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan