std::aligned_storage

出自cppreference.com
 
 
元編程庫
類型特徵
類型類別
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
類型屬性
(C++11)
(C++11)
(C++14)
(C++11)(C++26 棄用)
(C++11)(C++20 前*)
(C++11)(C++20 棄用)
(C++11)
類型特徵常量
元函數
(C++17)
受支持操作
關係與屬性查詢
類型修改
(C++11)(C++11)(C++11)
類型變換
(C++11)(C++23 棄用)
(C++11)(C++23 棄用)
(C++11)
(C++11)(C++20 前*)(C++17)

(C++11)
(C++17)
編譯時有理數算術
編譯時整數序列
 
在標頭 <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 對於某類型 T 必須為 alignof(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 所定義的類型能用於創建適合保有給定類型對象的未初始化內存塊,可選地進行比其自然對齊要求更嚴格的對齊,例如在緩存或頁的邊界上。

同任何其他未初始化存儲,使用布置 new 創建對象,並以顯式的析構函數調用銷毀它們。

可能的實現

除了默認實參,aligned_storage 也能通過 alignas 表達:

template<std::size_t Len, std::size_t Align /* 未实现默认对齐 */>
struct aligned_storage
{
    struct type
    {
        alignas(Align) unsigned char data[Len];
    };
};

示例

初步的靜態 vector 類,演示在對齊存儲中創建、訪問及析構對象。

#include <cstddef>
#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{};

        // 用原位 operator new 在对齐的存储中构造值
        ::new(&data[m_size]) T(std::forward<Args>(args)...);
        ++m_size;
    }

    // 在对齐的存储中访问对象
    const T& operator[](std::size_t pos) const 
    {
        // 注意:在 P0137R1 中的对象模型更改后需要 std::launder
        return *std::launder(reinterpret_cast<const T*>(&data[pos]));
    }

    // 从对齐的存储中销毁对象
    ~static_vector() 
    {
        for(std::size_t pos = 0; pos < m_size; ++pos) {
            // 注意:在 P0137R1 中的对象模型更改后需要 std::launder
            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) 指定該變量的存儲應該按指定量對齊
(specifier)[編輯]
獲取類型的對齊要求
(類模板) [編輯]
分配對齊的內存
(函數) [編輯]
(C++11 起)(C++23 棄用)
定義適於用作所有給定類型的未初始化存儲的類型
(類模板) [編輯]
具有不小於任何基礎類型的內存對齊需求的平凡類型
(typedef) [編輯]
(C++17)
指針優化屏障
(函數模板) [編輯]