Нужен ли в этом сценарии std::launder?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Нужен ли в этом сценарии std::launder?

Сообщение Anonymous »

В настоящее время я пытаюсь реализовать карту слотов, и у меня есть несколько проблем с управлением памятью, если у меня есть std::array, где Storage представляет собой следующую структуру:

Код: Выделить всё

struct Storage final
{
alignas(T) std::byte data[sizeof(T)];
};
нужно ли что-то подобное при доступе к элементам?:

Код: Выделить всё

[[nodiscard]] constexpr auto element_ptr(std::size_t idx) noexcept -> T*
{
return std::launder(reinterpret_cast(std::addressof(m_RawData[idx].data)));
}

[[nodiscard]] constexpr auto element_ptr(std::size_t idx) const noexcept -> T const*
{
return std::launder(reinterpret_cast(std::addressof(m_RawData[idx].data)));
}
В ссылке на cpp ничего не сказано о std::launder, когда речь идет о повторном использовании памяти:
https://en.cppreference.com/w/cpp/langu ... etime.html

В частном случае объекты могут создаваться в массивах беззнаковых символов или std::byte(начиная с C++17) (в в этом случае говорят, что массив обеспечивает хранилище для объекта), если
срок жизни массива начался и не закончился

хранилище для нового объекта полностью помещается в массив

нет объекта массива, который удовлетворял бы этим ограничениям, вложенным в массив.
Если эта часть массива ранее предоставляла хранилище для другого объекта, срок службы этого объекта заканчивается, поскольку его хранилище было использовано повторно, однако время жизни массива сам по себе не заканчивается (его хранилище не считается повторно использованным).

но при чтении про std::launder говорится следующее:

Код: Выделить всё

std::launder
не влияет на свой аргумент. Его возвращаемое значение должно использоваться для доступа к объекту. Таким образом, отбрасывание возвращаемого значения всегда является ошибкой.
Типичное использование std::launder включает в себя:
  • Получение указателя на объект, созданный в хранилище существующего объекта того же типа, где указатели на старый объект не могут быть повторно использованы (например, потому что любой объект является подобъектом базового класса);
  • Получение указателя на объект, созданный путем размещения new, из указателя на объект, предоставляющий хранилище для этого объекта.
Ограничение reachability гарантирует, что std::launder не может использоваться для доступа к байтам, недоступным через исходный указатель, тем самым мешая компилятору escape-анализа.

Правильно ли я понимаю, что это зависит от T, который хранится внутри хранилища, и для безопасности общая структура данных, предоставляющая необработанную память, должна отмывать указатели каждый раз при доступе к элементам?
Подвопрос 1) Может ли кто-нибудь объяснить мне, что подразумевается под этим?

нет объекта массива, который удовлетворял бы этим ограничениям, вложенным в массив.


Подробнее здесь: https://stackoverflow.com/questions/798 ... s-scenario
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»