◐ Shell
clean mode source ↗

std::aligned_storage - cppreference.com

提供: cppreference.com

<tbody> </tbody>

template< std::size_t Len, std::size_t Align = /*default-alignment*/ > struct aligned_storage;

(C++11以上)

Len 以下のサイズと Align の約数のアライメント要件を持つ任意のオブジェクトのための未初期化記憶域として使用するのに適したトリビアル標準レイアウト型であるメンバ型 type を提供します。

Align のデフォルト値は Len 以下のサイズのあらゆるオブジェクトのうち最も厳しい (大きな) アライメント要件です。 デフォルト値が使用されない場合、 Align は何らかの型 T に対する alignof(T) の値でなければならず、そうでなければ動作は未定義です。

Len == 0 の場合、動作は未定義です。

任意の拡張アライメントがサポートされるかどうかは処理系定義です。

メンバ型

名前 定義
type アライメント要件 Align を持つ少なくとも Len のサイズの POD 型

ヘルパー型

<tbody> </tbody>

template< std::size_t Len, std::size_t Align = /*default-alignment*/ > using aligned_storage_t = typename aligned_storage<Len, Align>::type;

(C++14以上)

ノート

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];
    };
};

aligned_storage 内にオブジェクトを作成し、アクセスし、破棄する、原始的な静的ベクタクラス。

#include <iostream>
#include <type_traits>
#include <string>

template<class T, std::size_t N>
class static_vector
{
    // properly aligned uninitialized storage for N T's
    typename std::aligned_storage<sizeof(T), alignof(T)>::type 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: needs std::launder as of C++17
        return *reinterpret_cast<const T*>(&data[pos]);
    }

    // Delete objects from aligned storage
    ~static_vector() 
    {
        for(std::size_t pos = 0; pos < m_size; ++pos) {
            // note: needs std::launder as of C++17
            reinterpret_cast<T*>(&data[pos])->~T();
        }
    }
};

int main()
{
    static_vector<std::string, 10> v1;
    v1.emplace_back(5, '*');
    v1.emplace_back(10, '*');
    std::cout << v1[0] << '\n' << v1[1] << '\n';
}

出力:

関連項目