2012-02-05 21 views
7

Aunque disfruto mucho de las nuevas funciones en C++ 11, a veces siento que me faltan algunas de sus sutilezas.std :: Inicialización de la lista de inicializadores de array en la lista de inicialización

La inicialización de la matriz int funciona bien, la inicialización del vector Element2 funciona bien, pero la inicialización de la matriz Element2 falla. Creo que la sintaxis correcta debería ser la línea no comentada, pero ninguno de los intentos de inicialización me ha salido bien.

#include <array> 
#include <vector> 

class Element2 
{ 
    public: 
      Element2(unsigned int Input) {} 
      Element2(Element2 const &Other) {} 
}; 

class Test 
{ 
    public: 
      Test(void) : 
        Array{{4, 5, 6}}, 
        Array2{4, 5}, 
        //Array3{4, 5, 6} 
        Array3{{4, 5, 6}} 
        //Array3{{4}, {5}, {6}} 
        //Array3{{{4}, {5}, {6}}} 
        //Array3{Element2{4}, Element2{5}, Element2{6}} 
        //Array3{{Element2{4}, Element2{5}, Element2{6}}} 
        //Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}} 
        {} 
    private: 
      std::array<int, 3> Array; 
      std::vector<Element2> Array2; 
      std::array<Element2, 3> Array3; 
}; 

int main(int argc, char **argv) 
{ 
    Test(); 
    return 0; 
} 

He intentado esto en g ++ 4.6.1 y 4.6.2 en MinGW.

¿Cómo debo proceder para inicializar esta matriz? ¿Es posible?

+0

Supongo que esto no tiene mucho que ver con las listas de inicialización. ¿Sería apropiado editar la pregunta para que sea más acertada? – rendaw

Respuesta

6

La forma correcta de hacerlo es Array{{4, 5, 6}}. No puede omitir llaves cuando inicializa un miembro con inicialización agregada. La única vez que se puede omitir llaves es en una declaración de la forma

T t = { ... } 

Así, en su caso, usted tiene que escribir todos los apoyos: Uno para el std::array sí mismo, y uno para la matriz int. Para Array3, su sintaxis es correcta también, ya que int se puede convertir a Element2 implícitamente.

De los comentarios restantes, el Array3{{{4}, {5}, {6}}}, Array3{{Element2{4}, Element2{5}, Element2{6}}} y Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}} funcionan también, pero son más prolijos. Sin embargo, conceptualmente, el Array3{{{4}, {5}, {6}}} produce la menor cantidad de temporales en implementaciones que no hacen copia elision (supongo que es irrelevante, pero es bueno saberlo), incluso menos que el Array3{{4, 5, 6}}, porque en lugar de inicialización de copia, utiliza la inicialización de la lista de copia para su Element2, que no produce un intermediario temporal por diseño.

+0

¿Está diciendo que debería funcionar bien y que GCC está roto? Porque el OP dice que * todas * estas variaciones fallan. Además, ¿cómo funciona esto realmente, ya que 'std :: array ' no es un agregado? Puedo citar las especificaciones para los requisitos en los agregados, y 'std :: array ' falla esa prueba. ¿Puedes citar las especificaciones sobre cómo un no agregado puede inicializarse a través de la inicialización agregada? No digo que estés equivocado. Admito libremente que nunca he leído completamente la especificación C++ 11. Al mismo tiempo, quisiera alguna evidencia sobre la veracidad de su reclamo. –

+1

@NicolBolas Según tengo entendido, 'std :: array ' es un agregado: es una estructura sin un constructor definido por el usuario, y se menciona explícitamente como un agregado en la descripción de ''. – hvd

+0

@nico what hvd says –

Cuestiones relacionadas