C++ Use of deleted function error
Solution 1
Your struct here:
struct weighted_pointer{ mutable int weight; unique_ptr<likeatree> ptr; };
contains a std::unique_ptr
. A std::unique_ptr
cannot be copied, so your entire weighted_pointer
cannot be copied as well.
There are three places in your code where you attempt to copy it, which causes the errors you see:
bool operator()(const weighted_pointer lhs, const weighted_pointer rhs) {
Must be:
bool operator()(weighted_pointer const& lhs, weighted_pointer const& rhs) {
stdSet.insert(tmp);
This could theoretically be fixed by:
stdSet.insert(std::move(tmp));
However, you then cannot use tmp
anymore, which you do, not only in the same loop but also in the loop below. So you must find a different solution altogether. Perhaps use emplace
. Or restructure your code entirely.
auto it = find_if(stdSet.begin(),stdSet.end(),[&](weighted_pointer temp){ return temp.ptr.get() == treeVector[i]; });
Must be:
auto it = find_if(stdSet.begin(),stdSet.end(),[&](weighted_pointer const& temp){ return temp.ptr.get() == treeVector[i]; });
For VC++ 2013, the std::move
fix will not suffice. You will have to add an explicit move constructor to your struct:
struct weighted_pointer{
mutable int weight;
unique_ptr<likeatree> ptr;
weighted_pointer() = default;
weighted_pointer(weighted_pointer&& src) :
weight(std::move(src.weight)),
ptr(std::move(src.ptr))
{
}
};
VC++ 2015 fixes this problem. More information: Default Move Constructor in Visual Studio 2013 (Update 3)
Solution 2
Your weighted_pointer
is non-copyable because it contains a non-copyable member (the unique_ptr
), so you have to pass it by const reference to your comparator function.
bool operator()(const weighted_pointer& lhs, const weighted_pointer& rhs)
This is because if you pass it by value (as it is currently written), it will try to make a function-local copy.
You also cannot do this because you are trying to copy tmp
, which as I just said that struct
is non-copyable.
for(unsigned int i = 0; i < stdDeque.size(); i++){
tmp.ptr.reset(new likeatree{0,&stdDeque[i],nullptr});
stdSet.insert(tmp);
}
You can use emplace
to construct a weighted_pointer
in-place instead
for(unsigned int i = 0; i < stdDeque.size(); i++){
stdSet.emplace(1, std::make_unique<likeatree>(0,&stdDeque[i],nullptr));
}
Umuril Lyerood
Updated on August 04, 2020Comments
-
Umuril Lyerood over 3 years
I'm getting a lot of use of deleted function error. I just changed the pointer of
weighted_pointer
tounique_ptr
. But I can't realize why I'm getting the error, any tip?The
likeatree
is a DAG structure which can point to another struct or an element ofstdDeque
based on mask value.The
weight
ofweighted_pointer
hasmutable
keyword because doesn't change where in the set will be.#include <deque> #include <set> #include <vector> #include <iostream> #include <algorithm> #include <memory> #include <chrono> using namespace std; struct likeatree{ unsigned int mask : 3; void * a; void * b; }; struct weighted_pointer{ mutable int weight; unique_ptr<likeatree> ptr; }; struct ptrcomp{ bool operator()(const weighted_pointer & lhs, const weighted_pointer & rhs) { if(lhs.ptr->mask < rhs.ptr->mask) return true; if(lhs.ptr->mask > rhs.ptr->mask) return false; if(lhs.ptr -> a < rhs.ptr->a) return true; if(lhs.ptr->a > rhs.ptr->a) return false; return lhs.ptr->b < rhs.ptr->b; } }; vector<likeatree *> treeVector; deque<bool> stdDeque(3); vector<vector<bool>> boolMatrix{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}; set<weighted_pointer,ptrcomp> stdSet; int main(){ srand(time(NULL)); likeatree * first_pointer = new likeatree{0,&input[0],nullptr}; likeatree * second_pointer = first_pointer; unique_ptr<likeatree> tmp(first_pointer); weighted_pointer wp; wp.weight = 1; wp.pointer = move(tmp); stdSet.insert(move(wp)); // I'd like to do it inline(or more but with variables that end of scope here), but this don't work. (And i don't keep a copy of the pointer) // stdSet.insert(move(weighted_pointer{1,move(make_unique<likeatree>(*new likeatree{0,&input[0],nullptr}))})); return 0; }
Edit: Changed code with a single case of the problem Edit: Solved. Missing a dereference when using make_unique.