Подтвердить что ты не робот

С++ priority_queue базовый размер контейнера для контейнера

Я использую priority_queue с вектором в качестве базового контейнера. Однако я ожидаю, что размер кучи будет очень большим. Я знаю о проблемах с изменением размера динамической векторной емкости. Поэтому я ищу способы изначально выделить достаточное пространство для базового вектора в моем priority_queue. Есть ли какие-либо предложения для достижения этого?

Спасибо

4b9b3361

Ответ 1

Контейнерные адаптеры stdlib предоставляют "заднюю дверь" для доступа к базовому контейнеру: контейнер является защищенным членом с именем c.

Поэтому вы можете наследовать от адаптера, чтобы получить доступ к контейнеру:

#include <queue>
#include <iostream>

template <class T>
class reservable_priority_queue: public std::priority_queue<T>
{
public:
    typedef typename std::priority_queue<T>::size_type size_type;
    reservable_priority_queue(size_type capacity = 0) { reserve(capacity); };
    void reserve(size_type capacity) { this->c.reserve(capacity); } 
    size_type capacity() const { return this->c.capacity(); } 
};

int main()
{
    reservable_priority_queue<int> q;
    q.reserve(10000);
    std::cout << q.capacity() << '\n';
}

Если вам плохо о наследовании класса stdlib, используйте личное наследование и сделайте все методы priority_queue доступными с объявлениями using.

Ответ 2

Вы не можете напрямую обращаться к базовому контейнеру, чтобы изменить емкость. Тем не менее вы можете изменить контейнер, который используется внутри, на std::deque. Контейнер std::deque может быть немного медленнее (но не в примечании большого О), чем вектор, но его рост намного быстрее, так как ему не нужно переместить все существующие элементы.

Ответ 3

Используйте функцию reserve:

std::vector<Type>::reserve(size_t size)

Пример:

std::vector<int> vec;
vec.reserve(10000);
std::priority_queue<int> q (std::less<int>(), vec);

Ответ 4

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

Ответ 5

Как полагают Дэвид, использование std:: deque, вероятно, является хорошим решением. Колонки памяти достаточно малы, чтобы обычно оставлять большую часть вашей памяти, пока очередь растет. Однако это просто более безопасное решение, но не безопасное решение.

Если вы не слишком заботитесь об эффективности, вы можете использовать stlxxl, который является реализацией стандартной библиотеки шаблонов для особо больших данных Наборы. Таким образом, выделяемая память будет вашим жестким диском (библиотека также поддерживает несколько жестких дисков или сетевых дисков).