No padrão C ++ 20, diz-se que os tipos de matriz são do tipo vida útil implícita .
Isso significa que uma matriz para um tipo de duração não implícita pode ser criada implicitamente? A criação implícita de tal matriz não causaria a criação dos elementos da 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");
Esse código não é mais UB desde C ++ 20?
Talvez assim seja melhor?
//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");
Respostas:
Sim.
Sim.
É isso que torna
std::vector
implementável em C ++ comum.fonte
std::launder(static_cast<std::string*>(ptr))
não retorna um ponteiro para o primeiro elemento da matriz porque não está dentro de sua vida útil, mas questd::launder(static_cast<std::string(*)[10]>(ptr))
retorna um ponteiro para a matriz, porque a matriz está dentro de sua vida útil?std::launder
não seja realmente necessário, porque o eel.is/c++draft/intro.object#11 garante queptr
já apontará para o array?static_cast
astd::string (*) [10]
deve ser suficiente! tx.std::launder
será bem definido. Não há nenhumstd::string
objeto para o qual apontar, masptr
poderia apontar para a matriz, para que a conversão estática deixe o valor inalterado esptr
também aponte para a matriz. Comstd::launder
ele é o UB simplesmente por causa dosstd::launder
requisitos.