std::aligned_storage
| Definiert in der Kopfdatei <type_traits> |
||
| template< std::size_t Len, std::size_t Align = /* Standardausrichtung */ > struct aligned_storage; |
(seit C++11) (veraltet in C++23) |
|
Stellt den verschachtelten Typ type bereit, der TrivialType und StandardLayoutType erfüllt und zur Verwendung als uninitialisierter Speicher für jedes Objekt geeignet ist, dessen Größe höchstens Len beträgt und dessen Ausrichtungsanforderung ein Teiler von Align ist.
Der Standardwert von Align ist die strengste (größte) Ausrichtungsanforderung für jedes Objekt, dessen Größe höchstens Len beträgt. Wenn der Standardwert nicht verwendet wird, muss Align der Wert von alignof(T) für einen bestimmten Typ T sein, andernfalls ist das Verhalten undefiniert.
Das Verhalten ist undefiniert, wenn Len == 0.
Es ist implementierungsabhängig, ob erweiterte Ausrichtungen unterstützt werden.
Wenn das Programm Spezialisierungen für std::aligned_storage hinzufügt, ist das Verhalten undefiniert.
Inhalt |
[bearbeiten] Member-Typen
| Name | Definition |
type
|
ein trivialer und Standardlayout-Typ von mindestens der Größe Len mit der Ausrichtungsanforderung Align |
[bearbeiten] Hilfstypen
| template< std::size_t Len, std::size_t Align = /* Standardausrichtung */ > using aligned_storage_t = typename aligned_storage<Len, Align>::type; |
(seit C++14) (veraltet in C++23) |
|
[bearbeiten] Hinweise
Der von std::aligned_storage<>::type definierte Typ kann verwendet werden, um uninitialisierte Speicherblöcke zu erstellen, die für die Aufnahme von Objekten des angegebenen Typs geeignet sind, optional mit strengerer Ausrichtung als ihre natürliche Ausrichtungsanforderung, beispielsweise an einer Cache- oder Seitengrenze.
Wie bei jedem anderen uninitialisierten Speicher werden die Objekte mit Placement New erstellt und mit expliziten Destruktoraufrufen zerstört.
[bearbeiten] Mögliche Implementierung
Abgesehen vom Standardargument ist aligned_storage mit alignas ausdrückbar
template<std::size_t Len, std::size_t Align = /* default alignment not implemented */> struct aligned_storage { struct type { alignas(Align) unsigned char data[Len]; }; }; |
[bearbeiten] Beispiel
Eine primitive statische Vektor-Klasse, die die Erstellung, den Zugriff und die Zerstörung von Objekten in ausgerichtetem Speicher demonstriert.
#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'; }
Ausgabe
***** **********
[bearbeiten] Siehe auch
alignas (C++11) |
gibt an, dass der Speicher für die Variable um einen bestimmten Betrag ausgerichtet werden soll (Spezifizierer) |
| (C++11) |
erhält die Ausrichtungsvoraussetzungen des Typs (Klassenvorlage) |
| (C++17) |
alloziert ausgerichteten Speicher (function) |
| (seit C++11)(veraltet in C++23) |
definiert den Typ, der als uninitialisierter Speicher für alle gegebenen Typen geeignet ist (Klassenvorlage) |
| (C++11) |
trivialer Typ mit einer Ausrichtungsvoraussetzung, die so groß ist wie die jedes anderen Skalar-Typs (typedef) |
| (C++17) |
Zeigeroptimierungsbarriere (Funktionstemplate) |