对托管对象执行std :: optional和boost :: optional尊重对齐限制吗?

时间:2017-09-04 13:42:24

标签: c++ boost c++17 boost-optional stdoptional

如果某个类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

2 个答案:

答案 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更悲观,但也会使你的对齐正确。