Доступ к элементам очереди C ++ как массив - PullRequest
14 голосов
/ 04 мая 2011

Можно ли обращаться к элементам очереди как к массиву? Если нет, то какие контейнеры, похожие на очередь, могут?

Ответы [ 6 ]

34 голосов
/ 04 мая 2011

Эта задача идеально подходит для std :: deque .Он оптимизирован для добавления / удаления в конце, но также обеспечивает произвольный доступ к элементам в середине.Чтобы процитировать связанную статью:

Deque очень похож на вектор: подобно вектору, это последовательность, которая поддерживает произвольный доступ к элементам, вставка с постоянным временеми удаление элементов в конце последовательности , и линейное время вставки и удаления элементов в середине.

... deque также поддерживает постоянное время вставки и удаления элементов наначало последовательности

Так как он может эффективно добавлять / удалять с обоих концов, deque может эффективно использоваться как очередь с его методами push_back и pop_front:

std::deque<int> aDeque;

// enqueue
aDeque.push_back(1);
aDeque.push_back(2);

// dequeue
int top = aDeque.front();
aDeque.pop_front();

Доступ к таким элементам, как массив, означает использование оператора индекса

deque также поддерживает произвольный доступ через оператор индекса:

std::cout << aDeque[0];
4 голосов
/ 04 мая 2011

Можно ли обращаться к элементам очереди как к массиву?

Конечно! Пока базовый контейнер (по умолчанию deque) делает это, хотя вы можете назвать код плохими именами ...

template<class T, class C=std::deque<T> >
struct pubqueue : std::queue<T, C> {
  using std::queue<T, C>::c;

  static C& get_c(std::queue<T, C> &s) {
    return s.*&pubqueue::c;
  }
  static C const& get_c(std::queue<T, C> const &s) {
    return s.*&pubqueue::c;
  }
};

template<class T, class C>
C& get_c(std::queue<T, C> &a) {
  return pubqueue<T, C>::get_c(a);
}
template<class T, class C>
C& get_c(std::queue<T, C> const &a) {
  return pubqueue<T, C>::get_c(a);
}

int main() {
  std::queue<int> q;
  q.push(42);
  std::cout << get_c(q)[0] << '\n';

  pubqueue<int> p;
  p.push(3);
  std::cout << p.c[0] << '\n';

  return 0;
}

Обратите внимание на хитрость, которая позволяет вам изменять переменные std :: queue для публикации переменных и просто обращаться к члену контейнера напрямую. Это позволяет сохранить интерфейс push / pop (вместо push_back / pop_front и т. Д.) Интерфейса std :: queue.

2 голосов
/ 04 мая 2011

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

1 голос
/ 04 мая 2011

Из STL следующие контейнеры могут использовать доступ operator []: vector, dequeue, map, bitset.

Контейнер по умолчанию для использования - векторный контейнер.В вашем случае исключение очереди является наиболее ценным вариантом (потому что вы хотите иметь операции с очередями, а также произвольный доступ).

Просмотрите справочный лист, который показывает доступные операции для контейнеров STL: http://www.cplusplus.com/reference/stl/

Диаграмма для определения того, какой тип контейнера вам нужно использовать (внизу страницы): http://www.linuxsoftware.co.nz/cppcontainers.html

1 голос
/ 04 мая 2011

Вместо очереди используйте вектор. Очередь не использует оператор [].

1 голос
/ 04 мая 2011

Ответ, это зависит от реализации очереди.Очередь, предоставляемая Стандартной библиотекой шаблонов, не дает вам произвольного доступа к элементам через оператор индекса, потому что реализация произвольного доступа побеждает точку очереди.

Напомним, что Очередь - это структура данных, котораяобеспечивает первоочередное поведение.Это означает, что вам нужно по-настоящему заботиться о головном элементе, вот и все.Как только вам понадобится доступ к элементам, расположенным вне головы, у вас больше не будет очереди.

Теперь это не значит, что вы не можете реализовать свою собственную очередь поверх класса массива / вектора, но это не так.быть эффективным, так как массивы и векторы не идеальны для динамического добавления и удаления элементов.

...