Является ли t2
совершенно безопасным и эквивалентным t1
?
Нет. На самом деле, оба являются плохими.
t2
- это плохо по той причине, что NathanOliver указывает: он не выровнен. Вам нужно было бы написать:
alignas(X) std::byte storage[sizeof(X)];
t1
также эта проблема связана с тем, что вы почти наверняка захотите написать aligned_storage_t<sizeof(X), alignof(X)>
, а не просто aligned_storage_t<sizeof(X)>
. Если бы X
было переопределено, вы бы потеряли это здесь. Если бы X
был просто большим, но не требовал выравнивания, у вас получилось бы относительно многоуровневое хранилище.
t1
также плохо по особой причине: aligned_storage
не совсем гарантирует, чтоты думаешь это гарантирует. В частности, он гарантирует, что X
может соответствовать aligned_storage<sizeof(X)>
, но не гарантирует, что он может точно соответствовать . Спецификация просто:
Элемент typedef type
должен быть тривиальным типом макета стандарта, подходящим для использования в качестве неинициализированного хранилища для любого объекта, размер которого не превышает * 1034. * и выравнивание которого является делителем Align.
То есть aligned_storage<16>::type
гарантированно будет иметь размер не менее 16 байтов, но соответствующая реализация может легко дать вам 32. Или 4K. Это в дополнение к проблеме случайного использования aligned_storage<16>
вместо aligned_storage_t<16>
.
Вот почему P1413 существует как бумага: aligned_storage
- это плохо.
Таким образом, реальный ответ на самом деле - написать что-то вроде __aligned_membuf
:
template <typename T>
struct storage_for {
alignas(T) std::byte data[sizeof(T)];
// some useful constructors and stuff, probably some getter
// that gives you a T* or a T const*
};
в libstdc ++