为什么我会收到编译错误"use of deleted function 'std::unique_ptr ..."

Why am I getting compile error "use of deleted function 'std::unique_ptr ..."

本文关键字:ptr std unique function of 编译 为什么 use 错误 deleted      更新时间:2023-10-16

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

c:mingwincludec++6.1.0bitspredefined_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

为什么你仍然得到一个错误:

std::set_difference在内部复制:

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

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

如果你想让你的代码编译,使用std::shared_ptr。

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

std::unqiue_ptr的主要特点是它不能被复制。这是设计的结果,名字也告诉了你这么多。

然而,CompareDiff尝试按值获取其参数。这需要一份副本。相反,使用std::unique_ptr<..> const&—不需要复制。

你不能复制unique_ptr,因为它是一个被删除的函数,你可以移动唯一的指针来转移所有权,但是因为你想要一个函子来比较一些东西,你需要通过引用传递那些unique_ptr

使用unique_ptr<x>来表示函数假定x的所有权。

使用shared_ptr<x>表示函数是x的部分所有者。

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

关于传递智能指针的更多注意事项,Herb Sutter在CppCon演讲中有一些很好的想法。