union而不是aligned_storage_t作为容器

时间:2017-03-01 19:19:52

标签: c++ stl containers unions c++17

用于存储元素的容器std::list< T >/std::map< T >/std::set< T >(非完整列表)使用节点类型,它与T不同,与std::vectorstd::array

如果我将一些分配器A传递给它们,那么它将通过以下方式“转换”为node_allocator_type

using allocator_traits = typename std::allocator_traits< A >::template rebind_traits< node_type >;
using node_allocator_type = typename allocator_traits::allocator_type;

标准库实现(libc++libstdc++)可以使用std::aligned_storage_t< sizeof(T), alignof(T) >的模拟作为节点类型的组成部分作为存储值的位置输入T。对于类型T的值,“过去结束”或“根”元素可能没有存储空间。通过使用就地::operator new和最终手动调用析构函数,容器“手动”管理值的生命周期。

在表单

中使用单元素union是否有效
union U
{
    U() { ; }
    T value;
};

而不是std::aligned_storage_t< sizeof(T), alignof(T) >

std::aligned_storage_t的哪些属性(在内部可以实现为类型为char [sizeof(T)];的正确对齐的数组)在上述用例中至关重要,并优先于上述{{1}的所有潜在优势}?

1 个答案:

答案 0 :(得分:2)

首先,更接近的模拟实际上是:

node_modules

如果union U { U() { } ~U() { } T value; }; 不是简单的可破坏的话。

也就是说,当你想要一个文字类型时,T是必要的。不能在union构造函数中使用placement-new,以便开始使用。这是朝着这个方向的巨大胜利。

constexpr的一个优点是您无需担心aligned_storage_t重载T的可能性。 operator&()可能会做一些奇怪的事情,可能根本无法编译。 new (&u.value) T没有那个问题,而且比new (&storage) T更符合人体工程学。