Revisé esta página pero no puedo obtener el motivo de la misma. Allí se menciona que
"Es más sensato que no devuelva ningún valor y que requiera que los clientes usen front () para inspeccionar el valor al principio de la cola"
Pero inspeccionar un elemento desde front () también requería que ese elemento se copiara en lvalue. Por ejemplo, en este segmento de código
std::queue<int> myqueue;
int myint;
int result;
std::cin >> myint;
myqueue.push (myint);
/ * aquí se creará temporal en RHS que se asignará al resultado, y en caso de que se devuelva por referencia, el resultado se invalidará después de la operación pop * /
result = myqueue.front(); //result.
std::cout << ' ' << result;
myqueue.pop();
en la quinta línea, el objeto cout primero crea una copia de myqueue.front () y luego lo asigna al resultado. Entonces, cuál es la diferencia, la función pop podría haber hecho lo mismo.
void std::queue::pop();
).front()
también requería que ese elemento se copiara en lvalue", no, no es así.front
devuelve una referencia, no un valor. Puede inspeccionar el valor al que se refiere sin copiarlo.pop()
. Si lo usastd::queue<T, std::list<T>>
, no hay ninguna preocupación acerca de que la referencia proporcionadafront()
sea invalidada por unpush()
. Pero debes conocer tu patrón de uso y documentar tus limitaciones.Respuestas:
De hecho, podría haber hecho lo mismo. La razón por la que no lo hizo es porque una ventana emergente que devolvió el elemento emergente no es segura en presencia de excepciones (tener que regresar por valor y, por lo tanto, crear una copia).
Considere este escenario (con una implementación pop ingenua / inventada, para ilustrar mi punto):
Si el constructor de copia de T arroja un retorno, ya ha alterado el estado de la cola (
top_position
en mi implementación ingenua) y el elemento se elimina de la cola (y no se devuelve). Para todos los efectos (sin importar cómo detecte la excepción en el código del cliente), el elemento en la parte superior de la cola se pierde.Esta implementación también es ineficaz en el caso de que no necesite el valor emergente (es decir, crea una copia del elemento que nadie usará).
Esto se puede implementar de manera segura y eficiente, con dos operaciones separadas (
void pop
yconst T& front()
).fuente
pop
? eso es bastante contrario a la intuición. Podría ser nombradodrop
, y luego está claro para todos que no hace estallar el elemento, sino que lo deja caer ...pop
no devolver nada. Consulte, por ejemplo, en wikipedia .La página a la que ha vinculado responde a su pregunta.
Para citar toda la sección relevante:
C ++ está diseñado teniendo en cuenta la eficiencia, sobre la cantidad de líneas de código que el programador tiene que escribir.
fuente
pop
cual devuelve un valor.pop no puede devolver una referencia al valor que se elimina, ya que se elimina de la estructura de datos, entonces, ¿a qué debería referirse la referencia? Podría devolver por valor, pero ¿qué pasa si el resultado de pop no se almacena en ningún lugar? Entonces se pierde tiempo copiando el valor innecesariamente.
fuente
pop
devoluciones y el acto de regresar pueden resultar en una excepción. Obviamente, tendría que eliminar el elemento antes de devolverlo, y luego, si algo arroja, el elemento podría perderse irrevocablemente.value_type
tiene un constructor de movimiento nothrow, pero la interfaz de la cola sería diferente dependiendo del tipo de objeto que almacene en ella, lo que no sería útil.Con la implementación actual, esto es válido:
Si pop devuelve una referencia, como esta:
Entonces el siguiente código podría fallar, ya que la referencia ya no es válida:
Por otro lado, si devuelve un valor directamente:
Entonces necesitaría hacer una copia para que este código funcione, lo cual es menos eficiente:
fuente
A partir de C ++ 11 sería posible archivar el comportamiento deseado utilizando la semántica de movimiento. Al igual
pop_and_move
. Por lo tanto, no se llamará al constructor de copia y el rendimiento dependerá únicamente del constructor de movimiento.fuente
pop
excepciones sean mágicamente seguras.Puedes hacer esto totalmente:
O, si desea el valor en una variable, use una referencia:
Además de eso: la redacción 'más sensible' es una forma subjetiva de 'buscamos en los patrones de uso y encontramos más necesidad de una división'. (Tenga la seguridad: el lenguaje C ++ no está evolucionando a la ligera ...)
fuente
Creo que la mejor solución sería agregar algo como
donde value recibirá el valor reventado.
La ventaja es que podría implementarse usando un operador de asignación de movimiento, mientras que usar front + pop hará una copia.
fuente