std::aligned_storage
| Определено в заголовочном файле <type_traits>
|
||
template< std::size_t Len, std::size_t Align = /*выравнивание по умолчанию*/ > struct aligned_storage; |
(начиная с C++11) (устарело в C++23) |
|
Предоставляет вложенный тип type, который представляет собой тривиальный тип со стандартной компоновкой, подходящий для использования в качестве неинициализированного хранилища для любого объекта, размер которого не превышает Len и чьё требование выравнивания является делителем Align.
Значение по умолчанию Align является самым строгим (самым большим) требованием выравнивания для любого объекта, размер которого не превышает Len. Если значение по умолчанию не используется, Align должно быть значением alignof(T) для некоторого типа T, иначе поведение не определено.
Поведение не определено, если Len == 0.
Определяется реализацией, поддерживается ли какое-либо расширенное выравнивание.
Поведение программы, добавляющей специализации для std::aligned_storage не определено.
Типы-элементы
| Имя | Определение |
type
|
тривиальный тип со стандартным выравниванием размером не менее Len с требованием выравнивания Align
|
Вспомогательный тип
<tbody> </tbody> template< std::size_t Len, std::size_t Align = /*выравнивание по умолчанию*/ > using aligned_storage_t = typename aligned_storage<Len, Align>::type; |
(начиная с C++14) (устарело в C++23) |
|
Примечание
Тип, определённый с помощью std::aligned_storage<>::type, может использоваться для выделения неинициализированных блоков памяти, подходящих для хранения объектов данного типа, опционально выровненных более строго, чем их естественное требование выравнивания, например, на границе кеша или страницы.
Как и в случае с любой другой неинициализированной памятью, объекты создаются с помощью размещающего new и уничтожаются явными вызовами деструктора.
Возможная реализация
За исключением аргумента по умолчанию, aligned_storage выражается в терминах выравнивания:
template<std::size_t Len, std::size_t Align = /*выравнивание по умолчанию не реализовано*/>
struct aligned_storage
{
struct type
{
alignas(Align) unsigned char data[Len];
};
};
|
Пример
Примитивный статический векторный класс, демонстрирующий создание, доступ и уничтожение объектов в выровненной памяти.
#include <iostream>
#include <new>
#include <string>
#include <type_traits>
template<class T, std::size_t N>
class static_vector
{
// правильно выровненная неинициализированная память для N переменных типа T
std::aligned_storage_t<sizeof(T), alignof(T)> data[N];
std::size_t m_size = 0;
public:
// Создаёт объект в выровненной памяти
template<typename ...Args> void emplace_back(Args&&... args)
{
if( m_size >= N ) // возможная обработка ошибок
throw std::bad_alloc{};
// создание значения в памяти выровненного
// хранилища, используя размещающий оператор new
::new(&data[m_size]) T(std::forward<Args>(args)...);
++m_size;
}
// Доступ к объекту в выровненной памяти
const T& operator[](std::size_t pos) const
{
// Примечание: std::launder необходим после изменения объектной модели в P0137R1
return *std::launder(reinterpret_cast<const T*>(&data[pos]));
}
// Уничтожение объектов из выровненной памяти
~static_vector()
{
for(std::size_t pos = 0; pos < m_size; ++pos)
// Примечание: std::launder необходим после изменения объектной модели в P0137R1
std::destroy_at(std::launder(reinterpret_cast<T*>(&data[pos])));
}
};
int main()
{
static_vector<std::string, 10> v1;
v1.emplace_back(5, '*');
v1.emplace_back(10, '*');
std::cout << v1[0] << '\n' << v1[1] << '\n';
}
Вывод:
*****
**********
Смотрите также
спецификатор alignas(C++11)
|
указывает, что хранилище для переменной должно быть выровнено на определённую величину |
(C++11) |
получает требования к выравниванию типа (шаблон класса) |
(C++17) |
выделяет выровненную память (функция) |
(C++11)(устарело в C++23) |
определяет тип, подходящий для использования в качестве неинициализированного хранилища для всех данных типов (шаблон класса) |
(C++11) |
тривиальный тип с такими же высокими требованиями к выравниванию, как и у любого другого скалярного типа (определение типа) |
(C++17) |
барьер оптимизации указателя (шаблон функции) |