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