¿Por qué no se prefirió una sintaxis de llaves dobles para constructores que toman std :: initializer_list

Inicialización uniforme es una característica importante y útil de C ++ 11. Sin embargo, no puedes simplemente usar{} en todas partes desde:

std::vector<int> a(10, 0);    // 10 elements of value zero
std::vector<int> b({10, 0});  // 2 elements of value 10 and 0 respectively
std::vector<int> c{10, 0};    // 2 elements of value 10 and 0 respectively
std::vector<int> d = {10, 0}; // 2 elements of value 10 and 0 respectively

auto e(0);    // deduced type is int
auto f = 0;   // deduced type is int
auto g{0};    // deduced type is std::initializer_list<int>
auto h = {0}; // deduced type is std::initializer_list<int>

Señalando queinicialización agregada en p.std::arrays requiere el uso de{{}}, me parece que todo el problema conqué constructor de vectores se seleccionará podría haberse evitado al requerir un{{}} llamar a los constructores tomando unastd::initializer_list:

std::vector<int> i{10, 0};    // 10 elements of value zero
std::vector<int> j{{10, 0}};  // 2 elements of value 10 and 0 respectively
std::vector<int> k = {10, 0}; // 2 elements of value 10 and 0 respectively

auto l{0};    // deduced type is int
auto m{{0}};  // deduced type is std::initializer_list<int>
auto n = {0}; // deduced type is std::initializer_list<int>

Estoy seguro de que esto fue discutido, ¿cuáles fueron las razones en contra de esto? Se prefiere una cita / enlace de una propuesta estándar como respuesta.

Actualizar. - Hay un punto enN2532 que dice:

(3) Los posibles casos de ambigüedad desagradables ocurren solo para listas cortas de inicializadores [...]

(5) ¿Por qué las reglas del lenguaje obligan a los programadores que desean un control breve y ambiguo (por razones perfectamente buenas) a escribir más para complacer a los programadores que prefieren (por razones perfectamente buenas) ser más explícitos, y pueden serlo?

[...]

Suponga que un programador espera que se llame a f (X). ¿Cómo podría una f (Y) "secuestrar" una llamada?

(4) Suponga que X no tiene un constructor de lista de inicializadores, pero Y sí. En este caso, la prioridad dada a los constructores de la lista de inicializadores favorece al secuestrador (recuerde que asumimos que el programador de alguna manera esperaba que se llamara f (X)). Esto es análogo a alguien que espera que f (y) invoque f (X) usando una conversión definida por el usuario y alguien viene con una f (Y) que coincide exactamente.Creo que sería justo esperar que alguien que usa {...} recuerde la posibilidad de constructores de listas de inicializadores. [énfasis mío]

Supongo que la clave está enpuede ser, lo que significa que no tiene que usar una inicialización uniforme. Utilizando{} correctamente es difícil ya que:

no solo tiene que verificar el constructor al que desea llamar sino tambiénalguna constructor tomando uninitializer_list eso podría ganar (y probablemente lo hará) sobre él;

si escribes código usando{} y alguien en el futuro agrega unstd::initializer_list constructor su código podría romperse y hacerlosilenciosamente.

Incluso si tienes una claseA con los constructoresA(int, bool) yA(std::initializer_list<double>), el último será seleccionado sobre el primero paraA a{0, false}; (que IMO está loco), así que lo encuentroDe Verdad inicialización uniforme difícil de usar en clases que tienen opodría tener (se requieren superpoderes de bola de cristal)initializer_list constructores

El hecho de que tu código pueda romperse silenciosamente me preocupa mucho.

Respuestas a la pregunta(2)

Su respuesta a la pregunta