名前空間
変種
操作

std::aligned_storage

From cppreference.com
< cpp‎ | types
 
 
メタプログラミングライブラリ
型特性
型のカテゴリ
(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)
型の変換
aligned_storage
(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 = /* default-alignment */ >
struct aligned_storage;
(C++11以降)
(C++23で非推奨)

ネストされた型typeを提供する。これはTrivialTypeStandardLayoutTypeを満たし、サイズが最大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 = /* 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++23で非推奨)
与えられたすべての型の未初期化ストレージとして使用するのに適した型を定義する
(クラステンプレート) [編集]
他のどのスカラ型よりも大きいアライメント要件を持つ自明型
(typedef) [編集]
(C++17)
ポインタ最適化の障壁
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)