C++ vector de matrices


¿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

Author: ildjarn, 2011-05-18

2 answers

Desafortunadamente, std::array no tiene un constructor de lista inicializador. De hecho, no tiene ningún constructor definido por el usuario whatsoever esta "característica" es un remanente de C++03 donde omitir todos los constructores definidos por el usuario era la única manera de habilitar la inicialización de llaves de estilo C. Es en mi humilde opinión un defecto en el estándar actual.

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

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

Ok, no es así significa que tendríamos que usar llaves dobles en el inicializador (un par para array, otro par para el miembro data?

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

C (y consecuentemente C++) tiene una regla especial sobre la elisión de llaves, permitiendo la omisión de las llaves internas a menos que haya una ambigüedad. array explota esta característica, lo que nos permite escribir

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

Entonces, ¿por qué no funciona el ejemplo en el post original? Porque la elisión de llaves solo está permitida en el contexto de un agregado de estilo C inicialización, no si hay algo más complicado involucrado, como un constructor de lista de inicializador 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 del compilador. Aunque no estoy completamente seguro de ello.

Esta pregunta es algo relevante: ¿Cómo inicializo un array miembro con una lista de inicializadores?

 23
Author: JohannesD,
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 10:30:44

Esto funciona:

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

Investigando más profundamente, parece que std:: pair tiene un constructor que toma una lista inicializadora, 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.

 4
Author: TonyK,
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
2011-05-18 08:19:40