mapa valores predeterminados

6 minutos de lectura

avatar de usuario
Bill Kotsias

std::map<int,int> mapy;
++mapy[5];

¿Es seguro asumir que mapy[5] siempre será 1? quiero decir, lo haré mapy[5] obtener siempre el valor predeterminado de 0 antes de ‘++’, incluso si no se declara explícitamente, como en mi código?

  • Posible duplicado del valor predeterminado de std::map para el tipo incorporado

    – bobobobo

    21/04/2016 a las 16:40

  • @bobobobo: esta pregunta es más antigua que el valor predeterminado de std::map para el tipo incorporado, entonces el duplicado debe ser el valor predeterminado de std::map para el tipo incorporado.

    – promomonet

    22 de abril de 2016 a las 6:33

avatar de usuario
rep_movsd

Tan pronto como acceda al mapa con el [] operador, si la clave no existe, se agrega. El int obtiene la invocación de “inicialización de valor”, por lo que obtendrá un valor de 0.

  • Por lo que he experimentado, una primitiva no inicializada intel valor inicial es indefinido — es decir, puede ser 0, o puede ser -99765521. Alguna vez ha tenido un no inicializado int como una variable de clase y apareció uno de esos valores extravagantes en su programa? Dicho esto, probé esto y parece funcionar. #include <stdio.h> #include <map> using namespace std; int main() { map<int,int> m ; for( int i = 0 ; i < 100 ; i++ ) m[i]++ ; for( const pair<int,int>& p : m ) printf( "m[%d] => %d\n", p.first, p.second ) ; }

    – bobobobo

    2 de julio de 2013 a las 13:43

  • Funciona de una manera diferente a lo que piensas. intx; hace que x obtenga un valor indefinido int x = int(); Nuevamente x obtiene 0 class foo { int x; foo() : x() {} }; foo f; Aquí fx será cero

    – rep_movsd

    11/07/2013 a las 18:40

  • @bobobobo: Mira mi respuesta. La inicialización es más compleja que eso y tiene múltiples “modos de operación” según el contexto.

    – Carreras de ligereza en órbita

    16 mayo 2018 a las 13:09

  • En C ++, la memoria de pila y pila no se inicializa: un objeto se inicializa mediante su constructor predeterminado; el lenguaje tiene constructores predeterminados para tipos primitivos que los inicializan en 0 cuando lo invoca de la manera correcta Ver mi comentario anterior

    – rep_movsd

    2 de agosto de 2018 a las 13:37

  • @JohannesOvermann – corregido

    – rep_movsd

    20 de enero a las 7:12

Sí, es seguro asumir.

Los mapas operator[] se especifica así:([map.access])

Efectos: Si no hay una clave equivalente a x en el mapa, inserta value_type(std::move(x), T()) en el mapa.
Devoluciones: Una referencia a la mapped_type correspondiente a x en *this.

T() usos valor-inicialización para todos T excepto void ([expr.type.conv]/2)y valor-inicialización para un resultado primitivo en inicialización cero ([dcl.init]/7).

Por lo tanto, la expresión se evalúa como una referencia a un objeto con valor cero. ([dcl.init]/5).

los operator++ call luego incrementa ese objeto a uno, y se evalúa a uno.

(Todas las referencias son C++ 11.)

  • No tengo idea de por qué tu respuesta fue rechazada porque tienes razón. Eso es exactamente lo que dice la especificación (lo comprobé yo mismo).

    –Hans de Ruiter

    6 de junio de 2018 a las 4:38


avatar de usuario
raquel casey

La respuesta de Rep_Movsd está demasiado simplificada y es probable que conduzca a numerosos conceptos erróneos extremadamente peligrosos. Los tipos de datos primitivos en C++ no tienen inicializadores. Louis Brandy tuvo una charla maravillosa en la que discutió muchos errores comunes de C++ que se cometen en Facebook y un malentendido sobre cómo std::map<>[] funciona fue uno de los errores que discutió, este es un excelente recurso aunque no entra en detalles sobre cómo funciona std::map<>[] en realidad funciona

En general, los enteros no se inicializan y no están definidos como todos los tipos primitivos. Dicho esto cuando se usa con std::map<>[] el int tiene un valor predeterminado de cero establecido a través de un proceso llamado inicialización de valor. La inicialización de valores es un proceso que realmente funciona con estructuras en general. Por ejemplo,

struct Struct {
Struct() : memberVariable() {}
       int memberVariable;
};

Siempre inicializará el int a cero. Si las variables miembro fueran otros tipos primitivos, también tendrían valores de inicialización específicos. Por ejemplo, los siguientes tipos se inicializan mediante la inicialización de valores de esta manera:

booleano = falso
flotante = 0.0f
enumeración = (tipo de enumeración)0

puntero = puntero nulo
puntero a miembro = puntero de miembro nulo

Tenga mucho cuidado cuando trabaje con datos que no se hayan inicializado explícitamente. Una última cosa, considere el siguiente código

map<string, int> myMap;
cout << myMap["Foo"];

Este código no solo siempre inicializará el número entero a 0, sino que también insertará 0 en el mapa. Solo para recapitular rápidamente, los tipos de datos primitivos no están definidos si no se inicializan, pero en algunos casos, como con una estructura o la inicialización del valor del mapa, inicializará los datos primitivos con un valor específico.

  • “Los tipos de datos primitivos en C++ no tienen inicializadores” Esto está demasiado simplificado y es probable que conduzca a conceptos erróneos peligrosos. “no inicializado” No. Bueno, no del todo. Se llama inicialización por defecto pero sí, el resultado es un valor indeterminado (C++11 8.5/11). “son indefinidos” No. Indeterminado. “estructuras” C++ no tiene estructuras. “inicialización de valor” Correcto. El punto clave es el tipo diferente de inicialización utilizada. También tienes algunos empalmes de coma en tu prosa.

    – Carreras de ligereza en órbita

    16 mayo 2018 a las 13:00


  • Los tipos de datos primitivos no se inicializan con ningún valor de forma predeterminada. No tienen construcción por defecto. En algunos casos, tienen construcción de valor. La distinción que está tratando de hacer entre un comportamiento indefinido e indeterminado es absurda. Según el estándar C++ 11, los comportamientos indefinidos se definen como: “…construcción de programa erróneo o no portátil o de datos erróneos, para los cuales este estándar internacional no impone requisitos”, lo que significa esencialmente que se ha producido un error en la lógica o en el estado, y el resultado es desconocido. Nunca dije que las estructuras fueran de C++.

    – Rachel Casey

    16 mayo 2018 a las 13:12


  • “La distinción que está tratando de hacer entre un comportamiento indefinido e indeterminado es absurda”. Yo no hice la distinción, lo hizo el estándar. Si cree que es absurdo, por supuesto que puede presentar una objeción en la lista de correo del grupo de trabajo de ISO.

    – Carreras de ligereza en órbita

    16 mayo 2018 a las 13:13

  • “Nunca dije que las estructuras fueran de C++”. Si ya sabe esto, ¿por qué habló de estructuras en una pregunta de C++? Ahora ese es ¡absurdo!

    – Carreras de ligereza en órbita

    16 mayo 2018 a las 13:13

  • No. No es posible crear una estructura en C++. Solo es posible crear una clase usando el heredado struct palabra clave. El código que has mostrado contiene un clase. C++ no tiene estructuras. Lectura adicional: stackoverflow.com/a/36917400/560648 stackoverflow.com/a/34108140/560648

    – Carreras de ligereza en órbita

    16 mayo 2018 a las 13:23

Sí, el valor predeterminado será el predeterminado de ese tipo. Si desea otro valor predeterminado, puede crear una clase que se comporte como un int pero que tenga un constructor predeterminado diferente.

El valor por defecto de map será 0;

si desea cambiarlo a -1, el siguiente método puede ayudar.

#include <bits/stdc++.h>
using namespace std;
  
struct AnotherVal{
    int value = -1; // can be changed as per requirement 
};
  

int main()
{
    map<int, AnotherVal> tempmap;
    cout << tempmap[1].value << endl;
  
    return 0;
} 

producción:

-1

¡Espero que esto te ayude!

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad