我正在使用Dijkstra在图表中找到最短路径。我以前使用std :: set但我认为堆可以表现得更好。但是我在使用d_ary_heap或priority_queue时遇到了麻烦。 这是一个简化版本:
#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;
}
(我正在使用_cost和_id的包装来加快比较,如果您有兴趣,请参阅C++ Optimize if/else condition。)
这似乎是相关的错误行,我想它与移动或复制构造函数有关。
.../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
我正在使用gcc 4.6(-std = c ++ 0x)和boost 1.50。
答案 0 :(得分:1)
您的gcc版本未正确实现隐式删除功能的规则。该代码至少使用gcc 4.7。
快速解决方法是同时声明移动赋值运算符Entry& operator=(Entry&&)
。
一般情况下,我不建议将C++11
与不完全最新的编译器一起使用。
另外:你移动构造函数和复制构造函数表现奇怪。他们不复制/移动字符串。您可能想要更改它。如果你真的只需要一个字符串,那就把它变成一个静态成员。