Spec-Zone.ru › C++

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) указывает, что хранилище для переменной должно быть выровнено на определённую величину
alignment_of
(C++11)
получает требования выравнивания типа
(шаблон класса)
aligned_alloc
(C++17)
выделяет выровненную память
(функция)
aligned_union
(C++11)(устарело в C++23)
определяет тип, подходящий для использования в качестве неинициализированного хранилища для всех заданных типов
(шаблон класса)
max_align_t
(C++11)
тривиальный тип с требованием выравнивания, большим или равным требованию выравнивания любого другого скалярного типа
(typedef)
launder
(C++17)
барьер оптимизации указателей
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/types/aligned_storage

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API