【问题标题】:Compiler error with vector of deque of unique_ptr带有 unique_ptr 的双端队列向量的编译器错误
【发布时间】:2016-04-02 00:39:06
【问题描述】:

以下代码无法在 gcc 5.3 上编译,并出现编译器错误,抱怨以某种方式调用了 unique_ptr 的复制构造函数。有人可以解释为什么会这样吗?

#include <iostream>
#include <memory>
#include <deque>

using Foo = std::deque<std::unique_ptr<int>>;                                   


void foo() {                                                                    
  std::vector<Foo> a;                                                           
  a.emplace_back();   // this fails to compile                                                             
}

编译器错误的关键行是:

gcc-4.9.2/include/c++/4.9.2/bits/stl_construct.h:75:7: error: use of deleted function ‘std::unique_ptr&lt;_Tp, _Dp&gt;::unique_ptr(const std::unique_ptr&lt;_Tp, _Dp&gt;&amp;) [with _Tp = int; _Dp = std::default_delete&lt;int&gt;]’ { ::new(static_cast&lt;void*&gt;(__p)) _T1(std::forward&lt;_Args&gt;(__args)...); }

【问题讨论】:

  • 哦,是的,这是一团糟。
  • 您应该包括&lt;vector&gt;&lt;deque&gt;,而不是&lt;queue&gt;。在这里并不重要。
  • 感谢您指出这一点。固定的。顺便说一句,如果我们将 std::deque 替换为 std::queue,则代码无法编译为相同的编译器错误。
  • @BarryTheHatchet。在问题中添加了错误消息。谢谢!

标签: c++ c++11


【解决方案1】:
  • vector::emplace_back 需要处理重新分配。
  • vector 重新分配时,现有元素将被移动,如果有的话

    • 它们不能被复制(由std::is_copy_constructible确定);或
    • 他们的移动构造函数是noexcept

    否则它们会被复制。这是为了维护强大的异常安全保障。

  • std::deque&lt;std::unique_ptr&lt;int&gt;&gt; 的移动构造函数不是 noexcept(根据实现,可能需要分配内存)。
  • std::deque&lt;std::unique_ptr&lt;int&gt;&gt; 可以根据std::is_copy_constructible 复制,因为它只检查是否存在具有正确签名的构造函数,而不是该构造函数的主体是否会真正编译。
  • vector::emplace_back 因此尝试复制它。
  • 编译器崩溃了。

【讨论】:

  • 这可以被认为是语言的缺陷吗?因为这是荒谬的。
  • @BarryTheHatchet:上次我戳了一下,它与有状态分配器有关。您无法在编译时判断两个分配器是否相等,因此在编译时您不知道是否可以移动或必须复制。
  • @MooingDuck 那是一个单独的野兽(移动任务)。
  • @BarryTheHatchet 由于自定义分配器constructs,我认为很难修复。您不能仅在 is_copy_constructible 等上进行 SFINAE,因为 construct 可以破坏参数。
  • @T.C.非常感谢!解释很有意义。不得不说这种行为很让人吃惊,推理也很微妙,尤其是deque move构造函数不是noexcept这一点。
猜你喜欢
  • 2013-02-18
  • 1970-01-01
  • 2015-05-01
  • 2014-03-14
  • 2012-04-03
  • 2017-03-20
  • 2020-10-29
  • 2021-02-21
  • 2018-05-18
相关资源
最近更新 更多