tiempo - La asignación en C++ ocurre a pesar de la excepción en el lado derecho
manual de programacion android pdf (3)
std :: map :: operator []
Devuelve una referencia al valor que se asigna a una clave equivalente a la clave, realizando una inserción si dicha clave aún no existe.
junk[id]
provoca la inserción mencionada anteriormente y, después de eso, ya ha ocurrido,
GetStuff()
lanza.
Tenga en cuenta que en C ++ 14 el orden en que suceden estas cosas se define por la implementación, por lo tanto, con un compilador diferente, su
junk[id] = GetStuff();
no puede hacer la inserción si
GetStuff()
lanza.
Tengo un código (C ++ 14) que se ve así:
map<int, set<string>> junk;
for (int id : GenerateIds()) {
try {
set<string> stuff = GetStuff();
junk[id] = stuff;
} catch (const StuffException& e) {
...
}
}
Esto funciona.
A veces,
GetStuff()
lanza una excepción, que funciona bien, porque si lo hace, entonces no quiero un valor en el mapa no deseado.
Pero al principio escribí esto en el bucle, que no funciona:
junk[id] = GetStuff();
Más precisamente, incluso cuando
GetStuff()
lanza una excepción, se crea
junk[id]
(y se le asigna un conjunto vacío).
Esto no es lo que yo esperaría: esperaría que funcionen de la misma manera.
¿Hay un principio de C ++ que no he entendido bien aquí?
Antes de C ++ 17, no había ninguna secuencia entre el lado izquierdo y el lado derecho de los operadores de asignación.
Es el primero en C ++ 17 que se introdujo la secuenciación explícita (el lado derecho se evalúa primero).
Eso significa que el orden de evaluación no está especificado , lo que significa que depende de la implementación realizar la evaluación en el orden en que lo desea, y en este caso, primero evalúa el lado izquierdo.
Consulte esta referencia de orden de evaluación para obtener más detalles (especialmente el punto 20).
No está entendiendo cómo funciona el
operator[]
en
std::map
.
Devuelve una referencia al elemento mapeado.
Por lo tanto, su código primero inserta un elemento predeterminado en esa posición y luego invoca
operator=
para establecer un nuevo valor.
Para que esto funcione de la manera que espera, deberá usar
std::map::insert
(*):
junk.insert(std::make_pair(id, GetStuff()));
Advertencia
:
insert
solo agregará el valor si la
id
no está asignada.