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
1034 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!

sumber:php.cn
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