C ++ Using deleted function error

I am getting a lot of benefit from the deleted function error. I just changed the pointer weighted_pointer

to unique_ptr

. But I can't figure out why I am getting an error, any feedback?

likeatree

is a DAG structure that can point to another structure or element stdDeque

based on a mask value.

weight

weighted_pointer

has a keyword mutable

because it 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 one case of problem Edit: Solved. No dereferencing when using make_unique.

+3


source to share


3 answers


Your structure is 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 full weighted_pointer

one cannot be copied either.

There are three places in your code where you are trying to copy it, which is causing errors:

bool operator()(const weighted_pointer lhs, const weighted_pointer rhs) {

      

Should be:

bool operator()(weighted_pointer const& lhs, weighted_pointer const& rhs) {

      

stdSet.insert(tmp);

      

This could theoretically be fixed with:



stdSet.insert(std::move(tmp));

      

However, you will no longer be able to use tmp

what you are doing, not only in the same loop, but also in the loop below. Therefore, you must find another solution. Maybe use emplace

. Or rebuild your code completely.

auto it = find_if(stdSet.begin(),stdSet.end(),[&](weighted_pointer temp){ return temp.ptr.get() == treeVector[i]; });

      

Should be:

auto it = find_if(stdSet.begin(),stdSet.end(),[&](weighted_pointer const& temp){ return temp.ptr.get() == treeVector[i]; });

      


For VC ++ 2013, the fix std::move

will not be sufficient. You will need to add an explicit move mechanism to your structure:

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

+3


source


Yours is weighted_pointer

not copied because it contains a non-copyable element ( unique_ptr

), so you need 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 currently written) it will try to create a local-local copy.

You also cannot do this because you are trying to copy tmp

, which, as I said, is struct

not 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 create weighted_pointer

instead

for(unsigned int i = 0; i < stdDeque.size(); i++){
    stdSet.emplace(1, std::make_unique<likeatree>(0,&stdDeque[i],nullptr));
}

      

+3


source


When I compile the code above, the compiler says:

In file included from /usr/include/c++/4.8/algorithm:62:0,
                 from 31791982.cpp:7:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of โ€˜_InputIterator std::__find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) [with _InputIterator = std::_Rb_tree_const_iterator<weighted_pointer>; _Predicate = main()::__lambda0]โ€™:
/usr/include/c++/4.8/bits/stl_algo.h:4465:41:   required from โ€˜_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = std::_Rb_tree_const_iterator<weighted_pointer>; _Predicate = main()::__lambda0]โ€™
31791982.cpp:55:124:   required from here

      

So, look at line 55 - what's going on:

    auto it = find_if(stdSet.begin(),stdSet.end(),[&](weighted_pointer temp){ return temp.ptr.get() == treeVector[i]; });

      

We are trying to copy weighted_pointer

from array to lambda temp

. But in fact, we'd be happy with the ref constant, so we const weighted_pointer&

'll replace it with and compile again:

/usr/include/c++/4.8/bits/stl_tree.h: In instantiation of โ€˜std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = weighted_pointer; _Val = weighted_pointer; _KeyOfValue = std::_Identity<weighted_pointer>; _Compare = ptrcomp; _Alloc = std::allocator<weighted_pointer>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = weighted_pointer]โ€™:
/usr/include/c++/4.8/bits/stl_tree.h:1377:47:   required from โ€˜std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = const weighted_pointer&; _Key = weighted_pointer; _Val = weighted_pointer; _KeyOfValue = std::_Identity<weighted_pointer>; _Compare = ptrcomp; _Alloc = std::allocator<weighted_pointer>]โ€™
/usr/include/c++/4.8/bits/stl_set.h:463:29:   required from โ€˜std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = weighted_pointer; _Compare = ptrcomp; _Alloc = std::allocator<weighted_pointer>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<weighted_pointer>; std::set<_Key, _Compare, _Alloc>::value_type = weighted_pointer]โ€™
31791982.cpp:49:26:   required from here

      

Line 49:

    stdSet.insert(tmp);

      

We cannot copy tmp

to a set. If we weren't going to reuse tmp

, we could have moved it instead:

for(unsigned int i = 0; i < stdDeque.size(); i++){
    weighted_pointer tmp;
    tmp.weight = 1;
    tmp.ptr.reset(new likeatree{0,&stdDeque[i],nullptr});
    stdSet.insert(std::move(tmp));
}

      

This way we leave us no problem for ptrcomp::operator()

which must accept its arguments by const reference.

0


source







All Articles