0

I am using a Dijkstra for finding a shortest path in graph. I used to use std::set but I think a heap could perform better. But I am having troubles using the d_ary_heap or the priority_queue. This is a simplified version:

#include <string>
#include <inttypes.h> // for uint32_t
#include <boost/heap/fibonacci_heap.hpp>
#include <boost/heap/binomial_heap.hpp>
#include <boost/heap/d_ary_heap.hpp>
#include <boost/heap/priority_queue.hpp>

using namespace std;

struct __attribute__ ((__packed__)) __attribute__((aligned(8)) Cmp {
    // Do *not* reorder the following two fields or comparison will break.
    const int32_t _id;
    const float _cost;

    Cmp(int32_t id, float cost) : _id(id), _cost(cost) {
        } 
};

struct Entry {
    Cmp _cmp;
    string str = "some variable";

    Entry(int32_t id, float cost) : _cmp(id, cost) {}
    Entry(Entry &&e) : _cmp(e._cmp._id, e._cmp._cost) {}
    Entry(const Entry &e) : _cmp(e._cmp._id, e._cmp._cost) {}
};

template<class T>
struct gt_entry: public binary_function <T, T, bool>
{
    bool operator()(const T &l, const T &r) const
    {
        return *(int64_t const *)&l > *(int64_t const *)&r;
    }
};


typedef boost::heap::d_ary_heap<
    Entry,
    boost::heap::arity<2>,
    boost::heap::compare<gt_entry<Entry> > > DHeap;

typedef boost::heap::binomial_heap<
    Entry,
    boost::heap::compare<gt_entry<Entry> > > BHeap;

typedef boost::heap::fibonacci_heap<
    Entry,
    boost::heap::compare<gt_entry<Entry> > > FHeap;


typedef boost::heap::priority_queue<
    Entry,
    boost::heap::compare<gt_entry<Entry> > > PQueue;



int main() {
    //DHeap h; // Doesn't compile
    //PQueue h; // Doesn't compile
    //BHeap h; // Works but slower than FHeap
    FHeap h; // Works but only  3% performance increase vs std::set

    h.push(Entry(1, 500.1));
    h.top();
    h.pop();

    return 0;
}

(I am using the packaging of the _cost and _id to speed up comparison, see C++ Optimize if/else condition if you are interested.)

This seems to be the relevant error line, I guess it has something to do with the move or copy constructor.

.../move.h:177:7: error: use of deleted function ‘Entry& Entry::operator=(const Entry&)’
heaps.cpp:19:8: note: ‘Entry& Entry::operator=(const Entry&)’ is implicitly declared as deleted because ‘Entry’ declares a move constructor or move assignment operator

I am using gcc 4.6 (-std=c++0x) and boost 1.50.

1 Answer 1

1

Your gcc version does not implement the rules for implicitly deleted functions correctly. The code works at least with gcc 4.7.

A quick workaround is to declare the move assignment operator Entry& operator=(Entry&&) as well.

In general I wouldn't recommend using C++11 with a compiler that is not completely up-to-date.

Also: You move constructor and copy constructor behave odd. They don't copy/move the string. You might want to change that. If you really only need one string across, make it a static member.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, that worked, thank you! But I had to do it like this: Entry operator=(Entry&&). I compile with 4.72, but eventually the code has to compile under 4.6... I just put in the string to show this struct contains more variables (also strings containers and stuff) in reality. It's just an example where the error occurred.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.