¿Por qué auto x{3} deduce una lista de inicializadores?


Me encanta auto en C++11. Es maravilloso. Pero tiene una inconsistencia que realmente me pone de los nervios, porque tropiezo con ella todo el tiempo:

int i = 3;       // i is an int with value 3
int i = int{3};  // i is an int with value 3
int i(3);        // i is an int with value 3 (possibly narrowing, not in this case)
int i{3};        // i is an int with value 3

auto i = 3;      // i is an int with value 3
auto i = int{3}; // i is an int with value 3
auto i(3);       // i is an int with value 3
auto i{3};       // wtf, i is a std::initializer_list<int>?!

Este extraño comportamiento es confuso para los recién llegados, y molesto para los usuarios experimentados C C++ tiene suficientes pequeñas inconsistencias y casos de esquina que uno tiene que tener en cuenta como está. ¿Puede alguien explicar por qué el comité de normas decidió introducir uno nuevo en este caso?

Podría entenderlo si declarara una variable de type std::initializer_list era algo que era útil o se hacía con frecuencia, pero en mi experiencia casi nunca es deliberado -- y en los raros casos en los que querías hacerlo, cualquiera de

std::initializer_list<int> l{3};
auto l = std::initializer_list<int>{3};
auto l = {3}; // No need to specify the type

Funcionaría muy bien. Entonces, ¿cuál es la razón detrás del caso especial para auto x{i}?

Author: vaxquis, 2014-09-01

1 answers

Para hacer una larga historia corta:

  • una expresión inicializadora entre corchetes {} no tiene ningún tipo por sí misma
  • auto tiene que inferir información de tipo
  • int{3} obviamente significa "crear un var int con valor tomado de la lista inicializadora", por lo que su tipo es simplemente int y se puede usar en cualquier contexto más amplio (int i = int{3} funcionará y auto i = int{3} puede deducir tipo, porque el lado derecho es obviamente de tipo int)
  • {3} por sí mismo no tiene tipo ( no puede ser int, porque no es un valor sino una lista inicializadora ), por lo queauto no funcionaría, pero, debido a que el comité consideró que auto debería seguir funcionando en este caso, decidieron que el tipo "mejor" para la lista inicializadora (sí, sin tipo por definición) lo sería... std::initializer_list, como probablemente ya adivinaste.

Pero, como usted señaló, esto hizo que todo el comportamiento de auto bastante semánticamente inconsistente. Es por eso que hubo propuestas para cambiarlo - a saber N3681, N3912 y N3922 - presentados al comité. La propuesta anterior fue RECHAZADA como FI3 debido a que no hubo consenso del comité sobre este asunto, http://isocpp.org/files/papers/n3852.html#FI3 , current ( N3922 ) got adoptado ca. Q1 de 2015;

tl; dr puede suponer que compiladores compatibles con los estándares1 con compatibilidad con C++ de vanguardia2 o tienen la nueva semántica más sana ya está en su lugar, o lo tendrá en breve.

El Comité de Estandarización reconoció el problema al adoptar N3922 en el borrador de C++17.

- así que es

auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
auto x3{ 1, 2 }; // error: not a single element
auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
auto x5{ 3 }; // decltype(x5) is int

Ahora, para bien o para mal.

más leyendo:

Http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3681.html

Http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3912.html

Http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html

Http://scottmeyers.blogspot.com/2014/03/if-braced-initializers-have-no-type-why.html

Http://herbsutter.com/2014/11/24/updates-to-my-trip-report /


1GCC 5.1 (&up) aparentemente usa N3922 incluso en el modo C++11/C++14

2Clang 3.8, con la advertencia

Este es un cambio incompatible hacia atrás que se aplica a todas las versiones de lenguaje que permiten la deducción de tipos de auto (por solicitud del comité de C++).

 38
Author: vaxquis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:57