std::aligned_storage
Определён в заголовочном файле <type_traits> | ||
|---|---|---|
template< std::size_t Len, std::size_t Align = /* default-alignment */ > struct aligned_storage; | (начиная с C++11) (устарело в C++23) |
Предоставляет вложенный тип type, который соответствует требованиям TrivialType и StandardLayoutType и подходит для использования в качестве неинициализированного хранилища для любого объекта, размер которого не превышает Len, а его требование к выравниванию является делителем Align.
Значением Align по умолчанию является самое строгое (наибольшее) требование к выравниванию для любого объекта, размер которого не превышает Len. Если значение по умолчанию не используется, Align должно быть значением alignof(T) для некоторого типа T, иначе поведение не определено.
Поведение не определено, если Len == 0.
Поддержка любого расширенного выравнивания определяется реализацией.
Если программа добавляет специализации для std::aligned_storage, поведение не определено.
Типы-члены
| Имя | Определение |
|---|---|
type | тривиальный тип со стандартным расположением, размером не менее Len и требованием к выравниванию Align |
Вспомогательные типы
template< std::size_t Len, std::size_t Align = /* default-alignment */ > using aligned_storage_t = typename aligned_storage<Len, Align>::type; | (начиная с C++14) (устарело в C++23) |
Примечания
Тип, определённый посредством std::aligned_storage<>::type, можно использовать для создания неинициализированных блоков памяти, подходящих для размещения объектов заданного типа, при необходимости с более строгим выравниванием, чем их естественное требование к выравниванию, например, по границе кэш-линии или страницы.
Как и в случае с любым другим неинициализированным хранилищем, объекты создаются с помощью размещающего new и уничтожаются явными вызовами деструкторов.
Возможная реализация
За исключением аргумента по умолчанию, aligned_storage можно выразить с помощью alignas:
template<std::size_t Len, std::size_t Align = /* default alignment not implemented */>
struct aligned_storage
{
struct type
{
alignas(Align) unsigned char data[Len];
};
};
|
Пример
Примитивный класс статического вектора, демонстрирующий создание, доступ и уничтожение объектов в выровненном хранилище.
#include <cstddef>
#include <iostream>
#include <new>
#include <string>
#include <type_traits>
template<class T, std::size_t N>
class static_vector
{
// Properly aligned uninitialized storage for N T's
std::aligned_storage_t<sizeof(T), alignof(T)> data[N];
std::size_t m_size = 0;
public:
// Create an object in aligned storage
template<typename ...Args> void emplace_back(Args&&... args)
{
if (m_size >= N) // Possible error handling
throw std::bad_alloc{};
// Construct value in memory of aligned storage using inplace operator new
::new(&data[m_size]) T(std::forward<Args>(args)...);
++m_size;
}
// Access an object in aligned storage
const T& operator[](std::size_t pos) const
{
// Note: std::launder is needed after the change of object model in P0137R1
return *std::launder(reinterpret_cast<const T*>(&data[pos]));
}
// Destroy objects from aligned storage
~static_vector()
{
for (std::size_t pos = 0; pos < m_size; ++pos)
// Note: std::launder is needed after the change of object model in 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) | барьер оптимизации указателей (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/types/aligned_storage