2009-01-29 6 views
23

¿Alguien sabe por qué std :: queue, std :: stack y std :: priority_queue no proporcionan una función de miembro clear()? Tengo que uno falso así:¿Por qué los adaptadores estándar de contenedor C++ no proporcionan una función clara?

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

IIRC, clear() se proporciona por todo lo que podría servir como contenedor subyacente. ¿Hay alguna buena razón para que los adaptadores del contenedor no lo proporcionen?

Respuesta

18

Bueno, creo que esto se debe a que clear no se consideró una operación válida en una cola, una prioridad_cola o una pila (por cierto, deque no es un adaptador sino un contenedor).

La única razón para utilizar la cola de adaptador del recipiente en lugar del contenedor deque es para que quede claro que son realizar operaciones única cola, y ninguna otra operación. (from the sgi page on queue)

Por lo tanto, al usar una cola, todo lo que puede hacer es presionar/soltar elementos; borrar la cola puede verse como una violación del concepto FIFO. En consecuencia, si necesita borrar su cola, tal vez no sea realmente una cola y debería usar una deque.

Sin embargo, esta concepción de las cosas es un poco estrecha de mente, y creo que limpiar la cola como lo haces es bastante justo.

-1

Creo que depende de la implementación, hasta hace poco Microsoft STL no tenía claro en varios contenedores. (ahora lo hace, por ejemplo, this quick google result)

Sin embargo, borrar() es a menudo simplemente una llamada a borrar (begin(), end()), por lo tanto, implemente su propio equivalente y utilícelo.

Creo que el estándar se refiere a borrar como borrar en un rango de iterador, por lo que lo anterior es lo que proporcionarán la mayoría de las implementaciones. (eg Dinkumware's)

+3

stack, queue y priority_queue no tienen iteradores tampoco. – Reunanen

11

Deque tiene clear(). Ver, por ejemplo, http://www.cplusplus.com/reference/stl/deque/clear.html.

Sin embargo, la cola no. Pero ¿por qué elegirías cola sobre deque, de todos modos?

La única razón para utilizar la cola de adaptador del recipiente en lugar del contenedor deque es para que quede claro que son realizar operaciones única cola, y ninguna otra operación.

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

así que supongo claro() no es una operación de cola, a continuación.

2

Yo diría que es porque los adaptadores de contenedores no son contenedores.

-2

std :: queue, std :: deque, y std :: priority_queue son adaptadores de contenedor y solo proporcionan una pequeña cantidad de métodos para acceder al contenedor subyacente.

Puede borrar el contenedor subyacente, siempre que pueda acceder a él. Para hacer esto, crea el contenedor subyacente para pasar al constructor de apadptor.Por ejemplo:

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

... time passes ... 

d.clear(); 

Editar: Información adicional

Debería también le he advertido que andar con cuidado aquí como llamar a métodos en el contenedor subyacente, puede romper las suposiciones hechas por el adaptador. En ese sentido, la forma en que está actualmente limpiando la cola parece preferible.

+1

Daniel, esto no es correcto, el argumento del constructor para la cola solo se usa para _initializar_ la cola, no para pasar una referencia al contenedor real. En otras palabras, 'q' se inicializará con 'd's contents', pero borrar 'd' no afectará a 'q'. – codelogic

+0

Interesante: los constructores que miré no tomaron ninguna referencia directa a la colección ... –

+1

Inténtalo de nuevo, tienes razón. Los adaptadores mantienen una colección como valor, no como referencia, y los constructores de los adaptadores toman una referencia constante a una colección para la inicialización. Curiosamente, en VS2008, el miembro "c" de la cola es público. Está protegido en priority_queue. –

1

PUEDE borrar las colas (y std :: stack y priority_queue), siempre que lo herede. El contenedor se deja intencionalmente protegido para permitir esto.

+4

no debe heredar públicamente de los contenedores estándar, incluso si no agrega variables de instancia: eliminar la clase derivada a través de un puntero de clase base sin un destructor virtual dará como resultado un comportamiento indefinido (no se garantiza que ** no ** llame a la base) destructor de clase). –

Cuestiones relacionadas