Как сохранить ссылку на контейнер std :: priority_queue?

Я создаю std::priority_queue с помощью std::vector как контейнер.

Кажется, что приоритетная очередь создает копию контейнера, переданного ей в своем конструкторе, поскольку изменения, внесенные в контейнер после построения очереди, не отражаются в контейнере очереди.

Например, если я позвоню clear() в моем контейнере приоритетная очередь остается полной.

Есть ли способ сохранить ссылку на внутренний контейнер приоритетной очереди после создания?

1

Решение

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();
}
1

Другие решения

Нет, это невозможно сделать. Причина в том, что если бы у вас был доступ к базовому контейнеру, вы могли бы получить к нему доступ и изменить его, как если бы он не был приоритетной очередью, что было бы очень запутанным и противоречит желаемому сценарию использования std::priority_queue, который должен предоставить очередь.

Это с точки зрения стандартов, может быть, ваша реализация имеет расширение, которое разрешает такой доступ, но это было бы очень удивительно, и я не знаю никакой реализации, которая делает это. Вы должны обратиться к соответствующей документации, чтобы быть уверенным.

Сказав это, вы всегда можете предоставить обертку вокруг std::priority_queue, в котором хранится контейнер. Но я бы не советовал (как сказано выше) вы могли бы изменить его без семантики очереди.

5

По вопросам рекламы [email protected]