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
DDDasal
2024-11-14 10:46:011054semak imbas

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);
}

Kes 1: Menyebut move() dengan Rvalues

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

Object a = std::move(Object()); // Object() is temporary, hence prvalue

Instasiasi templat yang terhasil ialah:

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

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);
}

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);

Instasiasi move() yang terhasil ialah:

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

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 &&

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);
}

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:
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