Я создаю std::priority_queue
с помощью std::vector
как контейнер.
Кажется, что приоритетная очередь создает копию контейнера, переданного ей в своем конструкторе, поскольку изменения, внесенные в контейнер после построения очереди, не отражаются в контейнере очереди.
Например, если я позвоню clear()
в моем контейнере приоритетная очередь остается полной.
Есть ли способ сохранить ссылку на внутренний контейнер приоритетной очереди после создания?
std::priority_queue
является одним из немногих стандартных контейнеров, разработанных для получения.
Имеет защищенного члена c
который является контейнером.
Вы можете получить из очереди и использовать c
в вашем производном классе.
Если вы изменяете контейнер, помните, что это на самом деле heap
и должен иметь соответствующие функции кучи, примененные к нему, прежде чем покинуть ваш метод.
#include <queue>
#include <algorithm>
struct my_special_queue : std::priority_queue<int>
{
using underlying_queue = std::priority_queue<int>;
// re-use all constructors
using underlying_queue::underlying_queue;
// add a clear method
void clear()
{
underlying_queue::c.clear();
}
void remove_all_odd_numbers()
{
c.erase(std::remove_if(c.begin(), c.end(),
[](auto&&x) { return (x % 2) == 1; }),
c.end());
std::make_heap(c.begin(), c.end(),
underlying_queue::comp);
}
};
int main()
{
my_special_queue q;
// standard priority_queue methods
q.push(1);
q.push(2);
q.push(9);
q.push(6);
q.push(4);
q.push(7);
if (not q.empty()) {
q.top();
q.pop();
}
// apply our custom functions
q.clear();
q.remove_all_odd_numbers();
}
Нет, это невозможно сделать. Причина в том, что если бы у вас был доступ к базовому контейнеру, вы могли бы получить к нему доступ и изменить его, как если бы он не был приоритетной очередью, что было бы очень запутанным и противоречит желаемому сценарию использования std::priority_queue
, который должен предоставить очередь.
Это с точки зрения стандартов, может быть, ваша реализация имеет расширение, которое разрешает такой доступ, но это было бы очень удивительно, и я не знаю никакой реализации, которая делает это. Вы должны обратиться к соответствующей документации, чтобы быть уверенным.
Сказав это, вы всегда можете предоставить обертку вокруг std::priority_queue
, в котором хранится контейнер. Но я бы не советовал (как сказано выше) вы могли бы изменить его без семантики очереди.