【发布时间】:2014-07-08 19:34:24
【问题描述】:
我正在尝试编写一个优先队列/堆实现,它允许迭代、删除元素、在迭代期间更改键和值,以及查找具有特定键的所有元素。 std::priority_queue 不支持迭代,boost::heap 不支持在迭代期间更改键和值。我也尝试过使用std::multimap,但在迭代期间更改值也存在问题。
我的队列存储为std::pairs<double, T> 的std::vector。我想我可以使用std::sort 和std::equal_range 函数而不定义我自己的比较器,因为std::pair automatically overloads the < operator。此外,this question 建议将std::equal_range 与成对容器一起使用是可能的,但我收到std::equal_range 的以下编译器错误。
'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const double'
和
binary '<' : no global operator found which takes type 'std::pair<_Ty1,_Ty2>' (or there is no acceptable conversion)
我的猜测是这与使用模板有关,但在这种情况下,我也预计 std::sort 会失败。
总结
为什么
std::pair<的自动重载对std::equal_range不起作用?是否需要为我的优先级队列定义比较器?
我的实现如下
测试
int main()
{
PriorityQueue<double> queue;
queue.push(1, 1);
queue.remove(0);
queue.cleanup(); //This call throws the error when it calls std::equal_range
}
标题
#include <vector>
#include <utility>
#include <algorithm>
template<typename T>
class PriorityQueue
{
T item;
typedef typename std::vector<std::pair<double, T>>::iterator It;
private:
std::vector<std::pair<double, T>> queue;
bool isSorted;
bool hasRemoved;
void sort(){
std::sort(queue.begin(), queue.end());
};
public:
PriorityQueue():isSorted(true), hasRemoved(false){};
void push(double cost, T val)
{
isSorted = false;
queue.push_back(std::make_pair(cost, val));
};
void remove(int i)
{
hasRemoved = true;
isSorted = false;
queue[i].first = DBL_MAX; //Pushes element to end of list
};
void cleanup()
{
if(!isSorted) sort();
if(hasRemoved)
{
std::pair<It, It> remove = std::equal_range(queue.begin(), queue.end(), DBL_MAX); // This line throws the error
queue.erase(remove.first, remove.second);
}
};
};
【问题讨论】:
-
std::equal_range(queue.begin(), queue.end(), DBL_MAX);尝试将pair<double, T>与double进行比较。pair仅提供与另一个pair进行比较的operator<,按字典顺序比较每个对象的两个成员。 -
您可以通过从
priority_queue继承并访问底层容器来迭代它的内容。但是,它很可能是作为堆排序的,而不是排序的。
标签: c++