Почему стандартные контейнерные адаптеры С++ не обеспечивают четкую функцию?
Кто-нибудь знает, почему std:: queue, std:: stack и std:: priority_queue не предоставляют функцию-член clear()
? Я должен подделать один вот так:
std::queue<int> q;
// time passes...
q = std::queue<int>(); // equivalent to clear()
IIRC, clear()
обеспечивается всем, что может служить базовым контейнером. Есть ли веская причина, чтобы контейнерные адаптеры не предоставляли его?
Ответы
Ответ 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();
Изменить: дополнительная информация
Я также должен был предупредить вас протекционировать здесь, поскольку методы вызова в базовом контейнере могут нарушить предположения, сделанные адаптером. В этом отношении предпочтительнее то, как вы сейчас очищаете очередь.