En el estándar C ++ 20, se dice que los tipos de matriz son de tipo implícito de por vida .
¿Significa que se puede crear implícitamente una matriz a un tipo de vida no implícito? ¿La creación implícita de tal matriz no causaría la creación de los elementos de la matriz?
Considere este caso:
//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");
¿Este código ya no es UB desde C ++ 20?
Tal vez de esta manera es mejor?
//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");
Respuestas:
Si.
Si.
Esto es lo que hace que sea
std::vector
implementable en C ++ ordinario.fuente
std::launder(static_cast<std::string*>(ptr))
no devuelve un puntero al primer elemento de la matriz porque no está dentro de su vida útil, sino questd::launder(static_cast<std::string(*)[10]>(ptr))
devuelve un puntero a la matriz porque la matriz está dentro de su vida útil?std::launder
que no se necesita realmente, porque eel.is/c++draft/intro.object#11 garantiza queptr
ya apuntará a la matriz.static_cast
astd::string (*) [10]
debería ser suficiente! tx.std::launder
estará bien definido. No hay ningúnstd::string
objeto al que apuntar, peroptr
podría apuntar a la matriz, de modo que la conversión estática dejará el valor sin cambios y tambiénsptr
apuntará a la matriz. Constd::launder
esto es UB simplemente porstd::launder
los requisitos de.