Según cppreference.com, std::map::operator[]
para el valor no existente, la inicialización cero.
Sin embargo, el mismo sitio no menciona la inicialización cero para std::unordered_map::operator[]
, excepto que tiene un ejemplo que se basa en esto.
Por supuesto, este es solo un sitio de referencia, no el estándar. Entonces, ¿el código a continuación está bien o no?
#include <unordered_map>
int main() {
std::unordered_map<int, int> map;
return map[42]; // is this guaranteed to return 0?
}
std::optional
?std::optional
objeto que no contiene ningún valor contenido sigue siendo un objeto inicializado.std::optional
has_value
probarlo, pero falla, así que supongo que tienes razón.Respuestas:
Dependiendo de qué sobrecarga estamos hablando,
std::unordered_map::operator[]
es equivalente a [unord.map.elem](la sobrecarga de tomar un valor p-referencia sólo se mueve
k
entry_emplace
y es por lo demás idéntico)Si existe un elemento bajo la clave
k
en el mapa, entoncestry_emplace
devuelve un iterador a ese elemento yfalse
. De lo contrario,try_emplace
inserta un nuevo elemento debajo de la clavek
y devuelve un iterador a eso ytrue
[unord.map.modifiers] :Interesante para nosotros es el caso de que todavía no haya ningún elemento [unord.map.modifiers] / 6 :
(la sobrecarga de tomar un valor p-referencia sólo se mueve
k
enforward_as_tuple
y, de nuevo, es por lo demás idéntico)Como
value_type
es unpair<const Key, T>
[unord.map.overview] / 2 , esto nos dice que el nuevo elemento del mapa se construirá como:Como
args
está vacío cuando viene deoperator[]
, esto se reduce a nuestro nuevo valor que se construye como miembro de lospair
argumentos sin par [pair.pair] / 14, que es la inicialización directa [class.base.init] / 7 de un valor de tipoT
usando()
como inicializador que se reduce a inicialización de valor [dcl.init] /17.4 . La inicialización del valor de unint
es inicialización cero [dcl.init] / 8 . Y la inicialización cero de unint
naturalmente inicializa esoint
a 0 [dcl.init] / 6 .Entonces sí, su código está garantizado para devolver 0 ...
fuente
En el sitio que vinculaste dice:
Entonces el valor
int
está inicializado :Por eso es que el resultado es
0
.fuente