1. std::aligned_storage
插播一下POD的含義:Plain old data structure,縮寫爲POD,是C++語言的標準中定義的一類數據結構,POD適用於需要明確的數據底層操作的系統中。POD通常被用在系統的邊界處,即指不同系統之間只能以底層數據的形式進行交互,系統的高層邏輯不能互相兼容。比如當對象的字段值是從外部數據中構建時,系統還沒有辦法對對象進行語義檢查和解釋,這時就適用POD來存儲數據。
可能的源碼實現:
// PR c++/56859
// { dg-require-effective-target c++11 }
template<unsigned size, unsigned alignment>
struct aligned_storage
{
using type = struct { alignas(alignment) unsigned char data[size]; };
};
template <unsigned Len, unsigned Align>
struct aligned_storage
{
using type __attribute__((aligned((Align)))) =
char[Len];
};
// PR c++/17743
template <unsigned Len, unsigned Align>
struct aligned_storage
{
typedef char type[Len] __attribute__((aligned((Align))));
};
示例代碼:
#include <iostream>
#include <type_traits>
#include <string>
template<class T, std::size_t N>
class static_vector
{
// N 個 T 的正確對齊的未初始化存儲
typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N];
std::size_t m_size = 0;
public:
// 於對齊存儲創建對象
template<typename ...Args> void emplace_back(Args&&... args)
{
if( m_size >= N ) // 可行的錯誤處理
throw std::bad_alloc{};
new(data+m_size) T(std::forward<Args>(args)...);
++m_size;
}
// 訪問對齊存儲中的對象
const T& operator[](std::size_t pos) const
{
// 注意: C++17 起需要 std::launder
return *reinterpret_cast<const T*>(data+pos);
}
// 從對齊存儲刪除對象
~static_vector()
{
for(std::size_t pos = 0; pos < m_size; ++pos) {
// 注意: C++17 起需要 std::launder
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';
}
運行結果:
***** **********
2. alignas
示例代碼:
// sse_t 類型的每個對象將對齊到 16 字節邊界
struct alignas(16) sse_t
{
float sse_data[4];
};
// 數組 "cacheline" 將對齊到 128字節邊界
alignas(128) char cacheline[128];
int main()
{
}
3. alignof
示例代碼:
#include <iostream>
struct Foo {
int i;
float f;
char c;
};
struct Empty {};
struct alignas(64) Empty64 {};
int main()
{
std::cout << "Alignment of" "\n"
"- char : " << alignof(char) << "\n"
"- pointer : " << alignof(int*) << "\n"
"- class Foo : " << alignof(Foo) << "\n"
"- empty class : " << alignof(Empty) << "\n"
"- alignas(64) Empty: " << alignof(Empty64) << "\n";
}
運行結果:
Alignment of - char : 1 - pointer : 8 - class Foo : 4 - empty class : 1 - alignas(64) Empty: 64
reference:
https://zh.cppreference.com/w/cpp/types/aligned_storage