下面是来自Loki singleton implementation的代码片段,它显示了它所谓的“MaxAlign Trick”。我认为这与对齐有关(duh!),但是试图与联盟内部提到的所有类型保持一致的目的是什么呢?如果没有它,Create()
内部的新布局会中断吗?
template <class T> struct CreateStatic
{
union MaxAlign
{
char t_[sizeof(T)];
short int shortInt_;
int int_;
long int longInt_;
float float_;
double double_;
long double longDouble_;
struct Test;
int Test::* pMember_;
int (Test::*pMemberFn_)(int);
};
static T* Create()
{
static MaxAlign staticMemory_;
return new(&staticMemory_) T;
}
// other code...
}
字符串
1条答案
按热度按时间j9per5c41#
MaxAlign
有两个用途。首先,它是C++11std::max_align_t
的实现:“一个普通的标准布局类型,其对齐要求至少与每个标量类型一样严格(一样大)。”(cppreference)。由于类型的对齐是具有最高对齐要求的数据成员的对齐,因此MaxAlign
的定义准确地告诉我们:一个保证具有最大值的类型。针对感兴趣的平台的对齐。其次,它也是一个足够大的缓冲区,可以包含
T
:字符串
考虑到这两个方面,
MaxAlign
提供了C++11特性std::aligned_storage_t<size, alignment>
(不考虑T
的过度对齐-它可能甚至不存在)。为什么需要:布局
new
要求缓冲器对于正在构造的示例适当地对准。如果没有这种“对齐技巧”,您可能会以未定义的行为结束。T
是一个未知类型,Loki通过为编译代码的平台选择最大对齐来规避任何风险。在现代代码中,您可能不会使用placement new,而是在堆栈上使用
static
对象,例如。型
但在20年前,这可能无法在编译器和/或多线程环境中正常工作(上述
T instance
的正确初始化只有在C++11 IIRC之后才能保证)。