繁体   English   中英

emplace_back 在来自 unique_ptr 的列表中

[英]emplace_back in a list from a unique_ptr

这不编译

  std::list<int> l;
  std::unique_ptr<int> p = std::make_unique<int>();
  l.emplace_back(std::move(p));

列表的内部存储是_List_node ,它只是指向底层数据的简单来回指针,这里是int 因此,列表可以窃取unique_ptr的内部指针并将其放回原处。

在我的完整用例中,我有一个大于int的对象列表,并且我使用这样的移动构造函数

  l.emplace_back(std::move(*p));

但这比窃取unique_ptr的指针要慢,因为我的底层类型的许多字段都被复制了。

为什么列表不接受从unique_ptr移动,还有另一个容器可以接受吗?

所以列表可以窃取 unique_ptr 的内部指针

不,它不能。 列表分配存储元素的节点。 元素类型的 object 对它没有用处。

只有 std::list 可以从另一个相同类型的std::list std::list中窃取元素。

为了避免移动,要么首先创建 object 作为列表的元素,要么不要尝试将其存储在一个列表中。 将 object 放在一处。

在移动速度很快的情况下——对于大多数类型来说, std::move(*p)就可以了。

_List_node的典型实现如下所示:

template<typename _Tp>
    struct _List_node : public __detail::_List_node_base
    {
#if __cplusplus >= 201103L
      __gnu_cxx::__aligned_membuf<_Tp> _M_storage;
      _Tp*       _M_valptr()       { return _M_storage._M_ptr(); }
      _Tp const* _M_valptr() const { return _M_storage._M_ptr(); }
#else
      _Tp _M_data;
      _Tp*       _M_valptr()       { return std::__addressof(_M_data); }
      _Tp const* _M_valptr() const { return std::__addressof(_M_data); }
#endif
    };

并且__alignment_membuf看起来大致是这样的:

  template<typename _Tp>
    struct __aligned_membuf
    {
      struct _Tp2 { _Tp _M_t; };

      alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
    };

因此,存储在列表中的数据作为_M_data / _M_storage成员变量完全包含在_List_node中(_List_node 只有一个_Tp分配, _List_node没有额外的分配)。

因此,列表节点没有指向它管理但包含它的数据的指针。

因此,没有办法窃取指针,存储在列表中的类型必须始终移动或复制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM