Рассмотрим следующий объект:
std::array<std::aligned_storage_t<sizeof(T), alignof(T)>, size> container;
Если я уже назвал размещение нового для первого элемента этого массива, я считаю вполне приемлемым сделать следующее:
reinterpret_cast<T *>(container.data());
Это связано с тем, что data()
возвращает указатель на базовый массив, который также можно рассматривать как указатель на первый элемент этого базового массива. Я разместил объект в этом месте с помощью размещения new, поэтому в этом месте находится объект типа T
.
Обратите внимание, что здесь должно быть допустимо reinterpret_cast
, а не цепочка static_cast
, см. static_cast и реинтерпретировать_каст для std::aligned_storage.
Однако что, если я на самом деле не назвал размещение новым? Законно ли мне создавать этот указатель, если я не разыменовываю его?
Моей мотивацией здесь является реализация std::vector
-подобного класса, поддерживаемого статическим массивом (поэтому без косвенного или динамического распределения). Я пытаюсь реализовать функцию-член data()
. Удобно иметь всегда действующий способ с нулевыми издержками для создания пары указатели + размер, которые представляют данные: data()
, size()
. Поскольку size()
вернет 0, в итоге я создаю указатель, который никогда не разыменовываю.
reinterpret_cast
сам по себе безопасен. - person T.C.   schedule 05.09.2015std::vector
и не использовать распределитель в стеке, используя параметр шаблона размера? Но в любом случае, просто делать гипс безопасно. - person Brandon   schedule 05.09.2015sizeof(void *) * 2
места для указателей внутри вектора. Это также приводит к тому, что все мои обращения проходят через указатели, а непрямой доступ может убить конвейерную обработку, в зависимости от того, насколько легко компилятор/процессор может это увидеть, и это то, что оптимизаторы не всегда хорошо делают. Я почти исключительно выполняю работу, в которой пространство накладных расходов равно времени накладных расходов. - person David Stone   schedule 05.09.2015However, what if I have not actually called placement new? Is it legal for me to construct this pointer, as long as I do not dereference it?
[basic.life]/5 До того, как началось время жизни объекта, но после того, как хранилище, которое будет занимать объект, было выделено ... любой указатель, ссылающийся на место хранения, в котором объект будет быть ... расположенным может использоваться, но только ограниченными способами ... Далее в параграфе подробно описываются эти способы. Все будет хорошо, пока вы остаетесь в этих пределах. - person Igor Tandetnik   schedule 05.09.2015