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.

Community
  • 1
  • 1
Heye
  • 603
  • 6
  • 14

1 Answers1

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.

pmr
  • 58,701
  • 10
  • 113
  • 156
  • 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. – Heye Dec 13 '12 at 09:14