std::launder
ancak bunun ne için olduğunu biliyorsanız iyi bir şekilde adlandırılır. Bellek aklama gerçekleştirir .
Makaledeki örneği düşünün:
struct X { const int n; };
union U { X x; float f; };
...
U u = {{ 1 }};
Bu ifade, U
ile ilk üyesini başlatarak toplam başlatma gerçekleştirir {1}
.
Çünkü n
bir olan const
değişken, derleyici varsaymak serbesttir u.x.n
eder hep 1 olmak.
Peki bunu yaparsak ne olur:
X *p = new (&u.x) X {2};
Çünkü X
önemsiz olan bu tamamen yasal koddur yüzden biz, onun yerine yenisini oluşturmadan önce eski nesneyi yok etmek gerekmez. Yeni nesnenin n
üyesi 2 olacaktır.
Öyleyse söyle bana ... ne u.x.n
dönecek?
Açık cevap 2 olacaktır. Ancak bu yanlıştır, çünkü derleyicinin gerçek bir const
değişkenin (sadece a değil const&
, beyan edilen bir nesne değişkeni const
) asla değişmeyeceğini varsaymasına izin verilir . Ama biz sadece değiştirdik.
[basic.life] / 8 , yeni oluşturulan nesneye eski değişkene / işaretçilere / referanslara erişmenin uygun olduğu durumları açıklar . Ve bir const
üyeye sahip olmak diskalifiye edici faktörlerden biridir.
Peki ... nasıl u.x.n
düzgün bir şekilde konuşabiliriz ?
Hafızamızı aklamak zorundayız:
assert(*std::launder(&u.x.n) == 2); //Will be true.
Kara para aklama, insanların paranızı aldığınız yeri izlemelerini önlemek için kullanılır. Bellek aklama, derleyicinin nesnenizi aldığınız yerden izlemesini önlemek için kullanılır , böylece artık uygulanamayan optimizasyonlardan kaçınmaya zorlar.
Diskalifiye edici faktörlerden bir diğeri, nesnenin türünü değiştirirseniz. std::launder
burada da yardımcı olabilir:
aligned_storage<sizeof(int), alignof(int)>::type data;
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));
[basic.life] / 8 , eskisinin deposuna yeni bir nesne atarsanız, eski nesneye işaretçilerle yeni nesneye erişemeyeceğinizi söyler. launder
bunu yan adım atmamızı sağlar.
std::launder
?std::launder
"const veya başvuru üyeleri olsa bile, aynı türdeki mevcut bir nesne tarafından işgal edilen depolamada oluşturulan bir nesneye bir işaretçi elde etmek için kullanılır."