std::aligned_storage (3) - Linux Manuals

std::aligned_storage: std::aligned_storage

NAME

std::aligned_storage - std::aligned_storage

Synopsis


Defined in header <type_traits>
template< std::size_t Len, std::size_t Align = /*default-alignment*/ > (since C++11)
struct aligned_storage;


Provides the nested type type, which is a trivial standard-layout type suitable for use as uninitialized storage for any object whose size is at most Len and whose alignment_requirement is a divisor of Align.
The default value of Align is the most stringent (the largest) alignment requirement for any object whose size is at most Len. If the default value is not used, Align must be the value of alignof(T) for some type T, or the behavior is undefined.
The behavior is undefined if Len == 0.
It is implementation-defined whether any extended_alignment is supported.

Member types


Name Definition
type the POD type of at least size Len with alignment requirement Align

Helper types


template< std::size_t Len, std::size_t Align = /*default-alignment*/ > (since C++14)
using aligned_storage_t = typename aligned_storage<Len, Align>::type;

Notes


The type defined by std::aligned_storage<>::type can be used to create uninitialized memory blocks suitable to hold the objects of given type, optionally aligned stricter than their natural alignment requirement, for example on a cache or page boundary.
As with any other uninitialized storage, the objects are created using placement_new and destroyed with explicit destructor calls.

Possible implementation


Except for default argument, aligned_storage is expressible in terms of 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];
      };
  };

Example


A primitive static vector class, demonstrating creation, access, and destruction of objects in aligned storage
// Run this code


  #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';
  }

Output:


  *****
  **********

See also


alignas_specifier specifies that the storage for the variable should be aligned by specific amount (C++11)


alignment_of obtains the type's alignment requirements
                  (class template)
(C++11)


aligned_union defines the type suitable for use as uninitialized storage for all given types
                  (class template)
(C++11)


max_align_t trivial type with alignment requirement as great as any other scalar type
                  (typedef)
(C++11)