В стандарте C ++ 20 говорится, что типы массивов являются неявными типами времени жизни .
Означает ли это, что массив неявного типа времени жизни может быть создан неявно? Неявное создание такого массива не будет вызывать создание элементов массива?
Рассмотрим этот случай:
//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");
Разве этот код больше не UB, так как C ++ 20?
Может быть, так лучше?
//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");
Ответы:
Да.
Да.
Это то, что делает
std::vector
реализуемым в обычном C ++.источник
std::launder(static_cast<std::string*>(ptr))
не возвращает указатель на первый элемент массива, потому что он не в пределах своего времени жизни, но чтоstd::launder(static_cast<std::string(*)[10]>(ptr))
возвращает указатель на массив, потому что массив находится в пределах его времени жизни?std::launder
действительности это не нужно, потому что eel.is/c++draft/intro.object#11 гарантирует, чтоptr
он уже будет указывать на массив?static_cast
чтобыstd::string (*) [10]
должно быть достаточно! ТХ.std::launder
хорошо определен. Нетstd::string
объекта для указания, но онptr
может указывать на массив, так что статическое приведение оставит значение без изменений и такжеsptr
будет указывать на массив. Сstd::launder
UB это просто из-заstd::launder
требований России.