Namespaces
Variants

std:: aligned_storage

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
aligned_storage
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
Определено в заголовке <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++23)
определяет тип, подходящий для использования в качестве неинициализированного хранилища для всех заданных типов
(шаблон класса)
тривиальный тип с требованием выравнивания таким же большим, как у любого другого скалярного типа
(typedef)
(C++17)
барьер оптимизации указателей
(шаблон функции)