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

Почему стандартные контейнерные адаптеры С++ не обеспечивают четкую функцию?

Кто-нибудь знает, почему std:: queue, std:: stack и std:: priority_queue не предоставляют функцию-член clear()? Я должен подделать один вот так:

std::queue<int> q;
// time passes...
q = std::queue<int>();  // equivalent to clear()

IIRC, clear() обеспечивается всем, что может служить базовым контейнером. Есть ли веская причина, чтобы контейнерные адаптеры не предоставляли его?

4b9b3361

Ответ 1

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

Единственная причина использования контейнера очередь адаптера вместо контейнера deque - дать понять, что вы выполнение только операций очереди и никаких других операций. (из страницы sgi в очереди)

Таким образом, при использовании очереди все, что вы можете сделать, это push/pop elements; освобождение очереди можно рассматривать как нарушение концепции FIFO. Следовательно, если вам нужно очистить свою очередь, возможно, это не очередь, и вам лучше использовать deque.

Однако эта концепция вещей немного ограничена, и я думаю, что очистка очереди, как и вы, достаточно справедлива.

Ответ 2

У Deque есть clear(). См., Например, http://www.cplusplus.com/reference/stl/deque/clear.html.

Однако очереди нет. Но почему вы все равно выбираете очередь над deque?

Единственная причина использования контейнера очередь адаптера вместо контейнера deque - дать понять, что вы выполнение только операций очереди и никаких других операций.

(http://www.sgi.com/tech/stl/queue.html)

Итак, я думаю, clear() не является операцией очереди.

Ответ 3

Я бы сказал, потому что контейнерные адаптеры не являются контейнерами.

Ответ 4

Вы можете очистить очереди (и std:: stack и priority_queue), если вы наследуете их. Контейнер намеренно оставлен защищенным, чтобы это разрешить.

#include <queue>

using namespace std;

class clearable_queue : public queue<int>
{
public:
  void clear()
    {
      // the container 'c' in queues is intentionally left protected
      c.clear();
    }
};   

int main(int argc, char** argv)
{
  clearable_queue a;
  a.clear();
}

Ответ 5

Я думаю, что это зависит от реализации - до недавнего времени Microsoft STL не обладала ясностью в отношении нескольких контейнеров. (теперь он, например этот быстрый результат Google)

Однако clear() часто является просто вызовом erase (begin(), end()), поэтому реализуйте свой собственный эквивалент и используйте это вместо этого.

Я думаю, что стандарт относится к понятию стирания по диапазону итераторов, поэтому выше всего то, что предоставит большинство реализаций. (например, Dinkumware)

Ответ 6

std:: queue, std:: deque и std:: priority_queue являются контейнерными адаптерами и предоставляют только небольшое количество методов для доступа к базовому контейнеру.

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

std::deque< int > d;
std::queue< int > q( d );

... time passes ...

d.clear();

Изменить: дополнительная информация

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