std::launderdiberi nama tepat, meskipun hanya jika Anda tahu untuk apa itu. Ia melakukan pencucian memori .
Perhatikan contoh di koran:
struct X { const int n; };
union U { X x; float f; };
...
U u = {{ 1 }};
Pernyataan itu melakukan inisialisasi agregat, menginisialisasi anggota pertama Udengan {1}.
Karena nmerupakan constvariabel, kompiler bebas untuk menganggap bahwa u.x.nharus selalu 1.
Jadi apa yang terjadi jika kita melakukan ini:
X *p = new (&u.x) X {2};
Karena Xsepele, kita tidak perlu menghancurkan objek lama sebelum membuat yang baru sebagai gantinya, jadi ini adalah kode hukum yang sempurna. Objek baru akan memiliki nanggotanya menjadi 2.
Jadi katakan padaku ... apa yang akan u.x.nkembali?
Jawaban yang jelas adalah 2. Tapi itu salah, karena kompiler diperbolehkan untuk berasumsi bahwa constvariabel yang benar-benar (bukan hanya a const&, tetapi variabel objek yang dideklarasikan const ) tidak akan pernah berubah . Tapi kami baru saja mengubahnya.
[basic.life] / 8 menjabarkan keadaan saat OK untuk mengakses objek yang baru dibuat melalui variabel / pointer / referensi ke yang lama. Dan memiliki constanggota adalah salah satu faktor yang mendiskualifikasi.
Jadi ... bagaimana kita bisa bicara dengan u.x.nbenar?
Kita harus mencuci ingatan kita:
assert(*std::launder(&u.x.n) == 2); //Will be true.
Pencucian uang digunakan untuk mencegah orang melacak dari mana Anda mendapatkan uang Anda. Pencucian memori digunakan untuk mencegah kompiler melacak di mana Anda mendapatkan objek Anda, sehingga memaksa untuk menghindari optimasi yang mungkin tidak berlaku lagi.
Faktor lain yang mendiskualifikasi adalah jika Anda mengubah jenis objek. std::launderdapat membantu di sini juga:
aligned_storage<sizeof(int), alignof(int)>::type data;
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));
[basic.life] / 8 memberi tahu kami bahwa, jika Anda mengalokasikan objek baru dalam penyimpanan yang lama, Anda tidak dapat mengakses objek baru melalui pointer ke yang lama. laundermemungkinkan kita untuk melangkah ke samping itu.
std::launder?std::launderdigunakan untuk "mendapatkan pointer ke objek yang dibuat dalam penyimpanan yang ditempati oleh objek yang sudah ada dari jenis yang sama, bahkan jika memiliki konst atau referensi anggota."