如果某个类T
具有对齐要求,例如alignas
关键字指定的对齐要求,std::optional<T>
和boost::optional<T>
是否保证尊重所述对齐?
如果它们只是T
对象和bool initialized
的包装类,那么它们会根据需要自动对齐T
成员,但标准和boost文档声明它们可以没有任何对象,处理昂贵的构造对象。据我所知,他们不仅仅包含T
。相反,它们似乎分配了一个缓冲区,T
可以手动构建或销毁T
。因此,C ++语言不会自动对齐缓冲区,因为它不是std::optional<T>
类型。
那么,boost::optional<T>
和T
是否正确对齐其托管的optional<T>::operator new
对象?他们是否也提供尊重对齐要求的optional<T>::operator new[]
和sum
?
答案 0 :(得分:5)
根据C ++ 17标准草案,符合std :: optional 的实现必须遵守其value_type
的对齐要求:
23.6.3类模板可选[optional.optional]
(...) 所包含的值应分配在可选存储区域中,适合于类型T对齐。
实现者可以使用可能包含值作为成员的联合,确保正确对齐。
正如托马斯在我查阅时已提到的那样,boost :: optional确保使用aligned_storage<T>
确保正确对齐
答案 1 :(得分:2)
在GNU C ++实现中,std::optional
派生自_Optional_Base<_Tp>
,而_Optional_payload<_Tp>
又包含 using _Stored_type = remove_const_t<_Tp>;
struct _Empty_byte { };
union {
_Empty_byte _M_empty;
_Stored_type _M_payload;
};
bool _M_engaged = false;
。这是一个包含多个特化的模板,所有特化都包含以下成员:
_M_payload
如您所见,boost::optional<T>
实际上是强类型的,因此任何对齐属性都应在此实现中正确执行。
Boost实现不使用union。相反,optional_base<T>
派生自 typedef aligned_storage<T> storage_type ;
bool m_initialized ;
storage_type m_storage ;
,其中只包含:
aligned_storage
boost::detail::max_align
的名称是一个线索; docs没有提到第二个模板参数是可选的,默认为-1,这意味着:host {
/deep/ app-child-component {
//your child style
}
}
,这意味着使用对齐包含一堆基本类型的联合类型长度为128位。所以(从粗略的阅读)Boost似乎比GNU更悲观,但也会使你的对齐正确。