Pregunta ¿El constructor predeterminado de std :: pair <> establece tipos básicos (int, etc) en cero?


Después de escribir:

std::pair<int, int> x;

¿Tengo garantizado que x.primero y x.segundo son ambos cero? ¿O podrían tener algún valor?

La razón por la que me importa es porque estoy tratando de determinar si un mapa cuyos valores son punteros garantiza devolver NULL si tengo acceso a un elemento que no está en el mapa. Es decir, si lo hago:

std::map<int, void*> my_map;
std::cout << int(my_map[5]) << std::endl;

entonces ¿tengo garantizado que obtendré cero (NULO)? ¿O es el comportamiento indefinido?


32
2018-01-26 21:41


origen


Respuestas:


Sí, esa garantía es cierta. Citando el estándar C ++ 11, §20.3.2 / 2-3:

constexpr pair();

2 Requiere:  is_default_constructible<first_type>::value es true y is_default_constructible<second_type>::value es true.
  3 Efectos: Value-initializes first y second.

Y §8.5 / 7:

A value-initialize un objeto de tipo T medio:

  • Si T es un tipo de clase (posiblemente cv calificado) con un constructor proporcionado por el usuario, luego el constructor predeterminado para T se llama (y la inicialización está mal formada si T no tiene un constructor por defecto accesible);
  • Si T es un tipo de clase no sindicalizada (posiblemente cv calificado) sin un constructor proporcionado por el usuario, entonces el objeto se inicializa en cero y, si TEl constructor predeterminado implícitamente declarado no es trivial, ese constructor es llamado.
  • Si T es un tipo de matriz, luego cada elemento tiene un valor inicializado;
  • de lo contrario, el objeto tiene cero inicialización.

Y, por último, §8.5 / 5:

A cero inicialización un objeto o referencia de tipo T medio:

  • Si T es un tipo escalar, el objeto se establece en el valor 0 (cero), tomado como una expresión de constante integral, convertido a T;
  • Si T es un tipo de clase no sindicalizada (posiblemente cv calificado), cada miembro de datos no estático y cada subobjeto de clase base tiene cero inicialización y el relleno se inicializa a cero bits;
  • Si T es un tipo de unión (posiblemente cv calificado), el primer miembro de datos con nombre no estático del objeto tiene cero inicialización y el relleno se inicializa a cero bits;
  • Si T es un tipo de matriz, cada elemento tiene cero inicialización;
  • Si T es un tipo de referencia, no se realiza inicialización.

29
2018-01-26 21:56



Desde C ++ 11 estándar, sección § 20.3.2

constexpr pair();
...
Effects: Value-initializes first and second.

Por lo tanto, está bien definido que la inicialización predeterminada de un std::pair<int, int> objeto dará como resultado que ambos miembros se establezcan en 0.


5
2018-01-26 21:55



Sí, tienen cero inicialización. Una cita de "The C ++ Programming Language" de Bjarne Stroustrup (3ª edición, Ch. 17.4.1.7):

El resultado de m[k] es equivalente al resultado de (*(m.insert(make_pair(k,V())).first)).second, dónde V() es el valor predeterminado del tipo mapeado. Cuando entiendes esa equivalencia, probablemente entiendas los contenedores asociativos.

Para las citas estándar, lo que significa inicializar por defecto mira las respuestas de los demás.


4
2018-01-26 22:02



Sí, el par llamará a los constructores por defecto.


2
2018-01-26 21:50