c++ arrays c++11 initializer-list

C++ vector de matrices



vector 2d c++ (2)

¿Por qué funciona esto?

std::pair<int, int> p = {1,2}; std::vector<std::pair<int, int>> vp = { {1,2}, {3,4} };

Pero esto no?

std::array<int, 2> a = {1,2}; // still ok std::vector<std::array<int, 2>> va = { {1,2}, {3,4} };

Usando g ++ 4.5.1 con -std=c++0x , la segunda línea falla con:

error: no se pudo convertir ''{{1, 2}, {3, 4}}'' a ''std::vector<std::array<int, 2u> >''

Gracias


Desafortunadamente, std::array no tiene un constructor de lista de inicializadores. De hecho, no tiene ningún constructor definido por el usuario, esta "característica" es un remanente de C ++ 03 donde omitir a todos los constructores definidos por el usuario fue la única manera de habilitar la inicialización de llaves de estilo C. Es IMHO un defecto en la norma actual.

Entonces, ¿por qué no funciona la inicialización de refuerzo incorporada en este caso? Veamos como se ve std::array bajo el capó:

template <typename T, int i> struct array { T data[i]; // ... }

Ok, entonces eso no significa que tendríamos que usar llaves dobles en el inicializador (un par para la array , otro par para el miembro de data ?

std::array<int, 2> a = { {1, 2} };

C (y, en consecuencia, C ++) tiene una regla especial sobre la elección de la abrazadera , que permite la omisión de las llaves internas a menos que haya una ambigüedad. array explota esta característica, permitiéndonos escribir.

std::array<int, 2> a = { 1, 2 };

Entonces, ¿por qué no funciona el ejemplo en el post original? Debido a que Brace Elision solo se permite en el contexto de una inicialización agregada de estilo C, no si hay algo más complicado involucrado, como un constructor de lista de inicializadores definido por el usuario.

Lo siguiente debería funcionar, sin embargo, tan feo como es:

std::vector<std::array<int, 2>> vp = { {{1,2}}, {{3,4}} };

El hecho de que no lo haga, al menos en gcc 4.5 y gcc 4.6, me parece indicar un error de compilación. Aunque no estoy completamente seguro de eso.

Esta pregunta es de alguna manera relevante: ¿Cómo inicializo una matriz miembro con una lista_inicializador?


Esto funciona:

std::vector<std::array<int, 2>> va = { std::array<int, 2>{1,2}, std::array<int, 2>{3,4} };

Al profundizar, parece que std :: pair tiene un constructor que toma una lista de inicializadores, pero std :: array no:

std::pair<int, int> p ({1,2}) ; // OK std::array<int, 2> a ({1,2}) ; // Invalid

Pero ahora estoy fuera de mi profundidad.