Dalam standar C ++ 20, dikatakan bahwa tipe array adalah tipe seumur hidup implisit .
Apakah ini berarti bahwa array ke tipe seumur hidup non-implisit dapat dibuat secara implisit? Pembuatan implisit array seperti itu tidak akan menyebabkan pembuatan elemen array?
Pertimbangkan kasus ini:
//implicit creation of an array of std::string
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");
Apakah kode ini bukan lagi UB sejak C ++ 20?
Mungkin cara ini lebih baik?
//implicit creation of an array of std::string
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to the array of 10 std::string"
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");
Jawaban:
Iya.
Iya.
Inilah yang membuat
std::vector
implementable dalam C ++ biasa.sumber
std::launder(static_cast<std::string*>(ptr))
tidak mengembalikan pointer ke elemen pertama array karena tidak dalam masa pakainya, tetapistd::launder(static_cast<std::string(*)[10]>(ptr))
mengembalikan pointer ke array, karena array berada dalam masa pakainya?std::launder
sebenarnya tidak diperlukan, karena eel.is/c++draft/intro.object#11 menjamin bahwaptr
sudah akan mengarah ke array?static_cast
untukstd::string (*) [10]
harus cukup! tx.std::launder
akan didefinisikan dengan baik. Tidak adastd::string
objek untuk menunjuk, tetapiptr
bisa menunjuk ke array, sehingga pemain statis akan meninggalkan nilai tidak berubah dansptr
akan menunjuk ke array juga. Denganstd::launder
itu adalah UB hanya karenastd::launder
persyaratan.