У меня была та же проблема, когда я хотел перебрать приоритетную очередь без удаления очереди (следовательно, уничтожая мою очередь). Я заставил это работать для меня, переписав мой указатель priority_queue на указатель на вектор (так как мой priority_queue
использует вектор в качестве своего контейнера). Вот как это выглядит:
class PriorityQueue {
private:
class Element {
int x;
//Other fields
...
..
//Comparator function
bool operator()(const Element* e1, const Element* e2) const {
// Smallest deadline value has highest priority.
return e1->x > e2->x;
}
};
// Lock to make sure no other thread/function is modifying the queue
// Ofcourse we can do our operation w/o lock. if we are sure what is happening in other functions
pthread_mutex_t lock;
std::priority_queue<Element*, std::vector<Element*>, Element> pq;
public:
PriorityQueue();
~PriorityQueue();
//print the all the elements of the queue
void print_queue_elements() {
std::vector<PriorityQueue::Element*> *queue_vector;
//Acquire the lock
pthread_mutex_lock(&lock);
//recast the priority queue to vector
queue_vector = reinterpret_cast<std::vector<PriorityQueue::Element*> *>(&pq);
for(std::vector<PriorityQueue::Element*>::iterator it = (*queue_vector).begin(); it != (*queue_vector).end(); it++) {
//Assuming Element class has string function
printf("My Element %s", (*it)->string);
//other processing with queue elements
}
//Release the lock
pthread_mutex_unlock(&lock);
}
//other functions possibly modifying the priority queue
...
..
.
};
Теперь, когда я использую reinterpret_cast, люди могут спорить о безопасности типов. Но в этом случае я уверен в том, что все остальные функции обращаются к очереди / изменяют ее (все они безопасны) ... и я считаю, что это гораздо лучший способ, чем копирование содержимого всей очереди в какой-либо другой контейнер.
Я действительно ожидал, что static_cast
будет работать .. так как priority_queue является адаптером над контейнером (вектором в нашем случае), но это не так, и мне пришлось использовать reinterpret_cast
.