C++11stlintermediate
std::aligned_union (C++11 Addition)
C++11 · Modern Revolution · Compiler flag: -std=c++11
Explanation
Provides storage suitable for any of a list of types, with size and alignment sufficient for the largest type. Useful for implementing variant types.
Real-World Scenario
Implement a tagged union that can hold any of several types efficiently.
Quick Snippet
snippet.cpp
#include <type_traits>
using Storage = std::aligned_union<0, int, double, std::string>::type;
Storage s;
new (&s) double(3.14);Full Example
aligned_union.cpp
// CodeNebula - C++11 Example: aligned_union
// Compile: g++ -std=c++11 -Wall -Wextra -o example aligned_union.cpp
// Demonstrates std::aligned_union to create storage large enough and
// properly aligned for any of the specified types. Useful for type-safe
// unions and variant implementations.
#include <iostream>
#include <type_traits>
#include <new>
#include <string>
#include <cstring>
struct Point { double x, y, z; };
int main() {
std::cout << "=== std::aligned_union ===" << std::endl;
// aligned_union provides storage for the largest of the given types
using Storage = std::aligned_union<0, int, double, Point>::type;
std::cout << "sizeof(int): " << sizeof(int) << std::endl;
std::cout << "sizeof(double): " << sizeof(double) << std::endl;
std::cout << "sizeof(Point): " << sizeof(Point) << std::endl;
std::cout << "sizeof(Storage): " << sizeof(Storage) << std::endl;
std::cout << "alignof(Storage):" << alignof(Storage) << std::endl;
// Storage is large enough for any of the types
static_assert(sizeof(Storage) >= sizeof(int), "fits int");
static_assert(sizeof(Storage) >= sizeof(double), "fits double");
static_assert(sizeof(Storage) >= sizeof(Point), "fits Point");
// Use the storage to hold different types
Storage store;
// Store an int
new (&store) int(42);
std::cout << "\nStored int: " << *reinterpret_cast<int*>(&store) << std::endl;
// Store a double (reuse same storage)
new (&store) double(3.14159);
std::cout << "Stored double: " << *reinterpret_cast<double*>(&store) << std::endl;
// Store a Point
new (&store) Point{1.0, 2.0, 3.0};
Point* p = reinterpret_cast<Point*>(&store);
std::cout << "Stored Point: (" << p->x << ", " << p->y << ", " << p->z << ")"
<< std::endl;
// The first template parameter is minimum size (0 means auto)
using Big = std::aligned_union<128, int, double>::type;
std::cout << "\naligned_union<128,...> size: " << sizeof(Big)
<< " (at least 128)" << std::endl;
static_assert(sizeof(Big) >= 128, "respects minimum size");
std::cout << "\nAll checks passed!" << std::endl;
return 0;
}
// Expected output:
// === std::aligned_union ===
// sizeof(int): 4
// sizeof(double): 8
// sizeof(Point): 24
// sizeof(Storage): 24
// alignof(Storage):8
//
// Stored int: 42
// Stored double: 3.14159
// Stored Point: (1, 2, 3)
//
// aligned_union<128,...> size: 128 (at least 128)
//
// All checks passed!
Run command
g++ -std=c++11 -Wall -Wextra -o example aligned_union.cpp