12

Am getting a huge compile error with message

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)); }

when I pass a custom comparator to STL set_difference function.

My code:

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());

 }

Am using gcc 6.1.0 on windows 7 machine.

What am I missing?

Regards.

PG

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
gath
  • 24,504
  • 36
  • 94
  • 124

4 Answers4

9

The chief feature of std::unqiue_ptr is that it cannot be copied. That's by design, and the name tells you as much.

However, CompareDiff tries to take its arguments by value. That requires a copy. Instead, take a std::unique_ptr<..> const& - no copy is needed.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Change the arguments, now passing references, but I still get the same errors. – gath Sep 26 '16 at 14:13
  • Well, obviously not the exact same error, but I can imagine you're trying to copy that pointer elsewhere too. – MSalters Sep 26 '16 at 14:22
9

The reason why you are still getting an error:

std::set_difference does copy internally:

Copies the elements from the sorted range [first1, last1) which are not found in the sorted range [first2, last2) to the range beginning at d_first.

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

If you want your code to compile, use std::shared_ptr instead.

Keep in mind, that the Standard Library is optimized for Objects and not for pointers. You will have to do the ownership management yourself if you use pointers.

Trevir
  • 1,253
  • 9
  • 16
  • how is shared_ptr different from unique_ptr, based on my problem? How would I replace my unique_ptr with shared_ptr's? – gath Sep 26 '16 at 15:31
  • `unique_ptr` has copy disabled, `shared_ptr` has copy allowed (note that it is a shallow copy though!) – Trevir Sep 26 '16 at 15:35
  • The program compiled thanks! but I wish the compiler would show me where exactly the copying operation is to happen when am using unique_ptr – gath Sep 27 '16 at 05:02
  • A bit late to the party, but maybe for future readers: `std::copy` is basically a for loop over 2 vectors, say `vec1` and `vec2`, and it does `vec2[i] = vec1[i];`. That `=` is what calls the copy constructor of your objects. Because you had `unique_ptr` it tried to call it's copy constructor, which is deleted, hence the error – dtasev Aug 12 '19 at 09:27
5

You cannot copy construct a unique_ptr since its a deleted function, you can move unique pointers to transfer ownership but since you want a functor to compare something you need to pass those unique_ptr by reference.

Adrian Lis
  • 647
  • 4
  • 20
1

Use a unique_ptr<x> to express that a function assumes ownership of an x.

Use a shared_ptr<x> to express that a function is part owner of an x.

If you indeed want to pass a unique_ptr and transfer ownership, you should move the smart pointer into the function argument.

More notes on passing smart pointers, and Herb Sutter has some good thoughts in this CppCon talk.

BoltzmannBrain
  • 5,082
  • 11
  • 46
  • 79