用于存储元素的容器std::list< T >/std::map< T >/std::set< T >
(非完整列表)使用节点类型,它与T
不同,与std::vector
或std::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}的所有潜在优势}?
答案 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
更符合人体工程学。