Try this:
#include <memory>
#include <list>
#include <iostream>
using namespace ::std;
bool ptrLess(unique_ptr<int>& ptr1, unique_ptr<int>& ptr2)
{
return *ptr1 < *ptr2;
}
int main()
{
unique_ptr<int> ptr1(new int(3));
unique_ptr<int> ptr2(new int(2));
unique_ptr<int> ptr3(new int(5));
list<unique_ptr<int>> list;
list.push_back(move(ptr1));
list.push_back(move(ptr2));
list.push_back(move(ptr3));
list.sort(ptrLess);
for (auto &element : list) {
cout << *element;
}
return 0;
}
The problem here is that you need to understand what a unique_ptr
actually aims to be:
When dealing with pointers/references, there are a hell lot of potential problems arising if there are several pointersrs/references referring to the same object.
unique_ptr
tries to avoid precisely that.
Therefore, you cannot create 2 unique_ptr
referring to the same object.
You cannot use your ptrLess()
function because calling it like
unique_ptr<int> ptr1(new int(3));
unique_ptr<int> ptr2(new int(2));
ptrLess(ptr1, ptr2);
because this would mean ptr1
an ptr2
would have to be copied and passed over to ptrLess()
- keyword here is 'call-by-value'.
Moreover, you cannot do
list<unique_ptr<int>> list;
unique_ptr<int> ptr1(new int(3));
unique_ptr<int> ptr1(new int(3));
because this too, would have to create a copy of ptr1
.
The solution here is to not pass the unique_ptr
s to ptrLess
as values, but as reference:
bool ptrLess(unique_ptr<int>& ptr1, unique_ptr<int>& ptr2);
And you dont pass copies into the list, but move your object there:
list.push_back(move(ptr1));
keyword here is 'move-semantics'.
This will invalidate the content of your ptr1
variable - the object has been moved out of ptr1
into the list.
I recommend having a look at the Rust language if you are more deeply interested in things like these ;)
As Baum mit Augen pointed out, the parameters to ptrLess
better be declared as const
:
bool ptrLess(const unique_ptr<int>& ptr1, const unique_ptr<int>& ptr2);
list
and a variablelist
in the same scope, that could easily cause problems for you – kmdrekostd::vector
elements. This is commonly underestimated by teaching staff it seems. – Baum mit Augen♦ptrLess
, then theptrLess
function would own the pointers it was comparing. Then, when the function was over, there would be no owner and theunique_ptr
destructor would delete whatever was being pointed to. Your result would be a (technically sorted) list of nullunique_ptr
s. – Daniel H