【问题标题】:Why am I getting compile error "use of deleted function 'std::unique_ptr ..."为什么我会收到编译错误“使用已删除的函数 'std::unique_ptr ...”
【发布时间】:2016-09-26 13:16:40
【问题描述】:

我收到一个巨大的编译错误消息

c:\mingw\include\c++\6.1.0\bits\predefined_ops.h:123:18: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Deduction; _Dp = std::default_delete<Deduction>]'
         { return bool(_M_comp(*__it1, *__it2)); }

当我将自定义比较器传递给 STL set_difference 函数时。

我的代码:

struct Value{
   std::string ded_code;
   float amount;
   Value(std::string code, float amt):ded_code(code), amount(amt){}
};

struct Deduction{
  std::string p_number;
  std::vector<std::unique_ptr<Value>> values;
  Deduction(string pnum, string code, float amt):p_number(pnum){ 
    auto val = std::make_unique<Value>(code, amt);
    values.emplace_back(move(val));
  }
};

class compute{
public:
   vector<unique_ptr<Deduction>> deductions;
   void fillDeductions(){
    // fill deductions
    ...
   }

};

class CompareDiff{
public:
  bool operator()(unique_ptr<Deduction>& ded1, unique_ptr<Deductions>& ded2){
    rPtr1 = ded1.get();
    rPtr2 = ded2.get();
    return ( rPtr1->p_number < rPtr2->p_number);
 }
};

...
int main(){
  ...
  // fill two deduction vectors
  Compute compA = Compute()
  compA.fillDeductions()

  Compute compB = Compute()
  compB.fillDeductions()

  vector<unique_ptr<Deduction>> diffs

  set_difference(compA.begin(), compA.end(),
                 compB.begin(), compB.end(),
             inserter(diffs, diffs.begin()), CompareDiff());

 }

我在 windows 7 机器上使用 gcc 6.1.0。

我错过了什么?

问候。

PG

【问题讨论】:

  • 你可能会想要auto rPtr1 = ded1.get(),但这可能是无关的。
  • @MSalters 他们可能根本不需要将ded1 转换为原始指针。只需像普通指针一样使用unique_ptrded1-&gt;p_number
  • 阅读文档。问题很明显。
  • @BaummitAugen:还在等你的回答,如果它这么明显的话。
  • 有什么理由不使用std::vector&lt;Deduction&gt; BTW?这可能会容易得多。

标签: c++


【解决方案1】:

还是报错的原因:

std::set_difference 在内部进行复制

将排序范围 [first1, last1) 中未在排序范围 [first2, last2) 中找到的元素复制到从 d_first 开始的范围内。

http://en.cppreference.com/w/cpp/algorithm/set_difference

如果要编译代码,请改用 std::shared_ptr。

请记住,标准库针对对象而不是指针进行了优化。如果您使用指针,则必须自己进行所有权管理。

【讨论】:

  • 根据我的问题,shared_ptr 与 unique_ptr 有何不同?如何用 shared_ptr 替换我的 unique_ptr?
  • unique_ptr 已禁用复制,shared_ptr 已允许复制(请注意,它是浅复制!)
  • 程序编译感谢!但我希望编译器能告诉我在使用 unique_ptr 时复制操作的确切位置
  • 派对有点晚了,但也许对未来的读者来说:std::copy 基本上是一个 for 循环超过 2 个向量,比如 vec1vec2,它确实是 vec2[i] = vec1[i];= 就是调用对象的复制构造函数。因为你有 unique_ptr 它试图调用它的复制构造函数,它被删除了,因此错误
【解决方案2】:

std::unqiue_ptr的主要特点是不可复制。这是设计使然,名称也说明了这一点。

但是,CompareDiff 尝试按值获取其参数。那需要一个副本。取而代之的是 std::unique_ptr&lt;..&gt; const&amp; - 不需要副本。

【讨论】:

  • 更改参数,现在传递引用,但我仍然得到相同的错误。
  • 好吧,显然不是完全相同的错误,但我可以想象你也在尝试将该指针复制到其他地方。
【解决方案3】:

您不能复制构造 unique_ptr,因为它是一个 已删除的函数,您可以移动唯一指针以转移所有权,但由于您希望仿函数比较某些内容,因此您需要将 unique_ptr 传递给参考

【讨论】:

    【解决方案4】:

    使用unique_ptr&lt;x&gt; 表示函数假定拥有x

    使用shared_ptr&lt;x&gt; 表示函数是x 的部分所有者。

    如果您确实想传递unique_ptr 并转移所有权,您应该将智能指针move 放入函数参数中。

    More notes on passing smart pointers,Herb Sutter 在this CppCon talk 有一些好的想法。

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 2021-12-10
      • 1970-01-01
      • 2021-12-28
      • 2012-03-13
      • 2015-07-23
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多