std:: aligned_storage
| Type traits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time rational arithmetic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time integer sequences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
(C++14)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовке
<type_traits>
|
||
|
template
<
std::
size_t
Len,
std::
size_t
Align
=
/* выравнивание по умолчанию */
>
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
=
/* выравнивание по умолчанию */
>
using aligned_storage_t = typename aligned_storage < Len, Align > :: type ; |
(начиная с C++14)
(устарело в C++23) |
|
Примечания
Тип, определённый как
std::aligned_storage<>::type
, может использоваться для создания неинициализированных блоков памяти, пригодных для хранения объектов заданного типа, с возможностью выравнивания более строгого, чем их естественное требование к выравниванию, например, на границе кэша или страницы.
Как и в случае с любым другим неинициализированным хранилищем, объекты создаются с использованием placement new и уничтожаются с помощью явных вызовов деструкторов.
Возможная реализация
За исключением аргумента по умолчанию, aligned_storage выражается через alignas:
template<std::size_t Len, std::size_t Align = /* выравнивание по умолчанию не реализовано */> 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)
|
тривиальный тип с требованием выравнивания таким же большим, как у любого другого скалярного типа
(typedef) |
|
(C++17)
|
барьер оптимизации указателей
(шаблон функции) |